Michael Kronberger
Michael Kronberger

Reputation: 143

Android encryption and decryption with AES doesn't return the expected result without special characters

I'm trying to encrypt and decrypt an abritrary string in android, which I want to send to a webserver.

My Teststring is the following:

wert wert [ aa ] wert

This are my functions for encryption and decryption:

public static String encrypt(String value, String key) {
    SecretKey secretKey;
    String ex;
    try {
        byte[] encodedKey = Base64.decode(key, Base64.DEFAULT);

        secretKey = new SecretKeySpec(encodedKey,
                "AES");
        Cipher encrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
        encrypt.init(Cipher.ENCRYPT_MODE, secretKey,ivSpec);
        byte[] valueDecode = value.getBytes("UTF-16");
        byte[] valueInput = Base64.decode(value, Base64.DEFAULT);
        byte[] valueOutput = encrypt.doFinal(valueInput);


        return 
                 Base64.encodeToString( valueOutput, Base64.DEFAULT );
    } catch (Exception e) {
        e.printStackTrace();
        ex = e.toString();
    }
//  Log.d(TAG, ex);
    return null;
}

private static String decrypt(String value, String key) {
    SecretKey secretKey;
    String ex;

    byte[] encodedKey;
    try {
        encodedKey = Base64.decode(key, Base64.DEFAULT);

        secretKey = new SecretKeySpec(encodedKey, 
                "AES");
        Cipher decrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
        decrypt.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        byte[] valueInput = Base64.decode(value,Base64.DEFAULT);
        byte[] valueOutput = decrypt.doFinal(valueInput);

        return Base64.encodeToString(valueOutput, Base64.DEFAULT);
    } catch ( Exception e) {
        e.printStackTrace();
    }
    return null;
}

When I execute encryption and decryption for the string I receive this result:

wertwertaawerg==

All spaces and [] characters are missing and also the ending of the received string is not correct.

Any suggestions why it is not working properbly?

I'm working on an Android Version 4.0.3.

Upvotes: 0

Views: 1450

Answers (2)

Artjom B.
Artjom B.

Reputation: 61952

This is an encoding problem. The first thing that you do with the plaintext is you decode it from Base 64 to get a byte array. Characters like spaces or [] are not part of the default Base 64 alphabet and will be automatically removed before further processing.

Usually you would use the following to get byte[] from a plaintext String:

// during encryption
byte[] valueDecode = value.getBytes("UTF-8");
byte[] valueOutput = encrypt.doFinal(valueDecode);

// during decryption
return new String(valueOutput, "UTF-8");

If it is possible that the ciphertext may be manipulated (malicious or not), you should add an integrity check to that. This is hard to do right with an HMAC in an encrypt-then-MAC scheme, so you should use an authenticated mode of operation like GCM or EAX.

Upvotes: 0

cketti
cketti

Reputation: 1377

Please don't attempt to build a (tiny) crypto system yourself. There are many things that can go wrong. See this blog post for more details: http://tozny.com/blog/encrypting-strings-in-android-lets-make-better-mistakes/

Once you've read that, head over to Github and use this code: https://github.com/tozny/java-aes-crypto

Update: According to the blog post the typical mistakes are:

  • Bad key generation
  • Out of date key generation (SecureRandom bug on old Android versions)
  • Use of ECB
  • Bad Padding
  • No integrity
  • Incorrect IV
  • Weak algorithms

At least the issues marked in bold are present in the OP's code.

Upvotes: 1

Related Questions