1

I'm trying to do AES encryption/decryption in my Android app. I've tried libs like Encryption, java-aes-crypto and implementations described in

No matter how approach I use the decrypt part is different from original data. I always have a result like this:

03-09 21:58:33.457 30329-30329/org.androidapp.test E/ERROR: BEFORE: sDuKOoRteaEUFtA3P0SllSTCpgKJN75FuyPLxdp/ctM=

03-09 21:58:33.459 30329-30329/org.androidapp.test E/ERROR: AFTER: PBSqM3jHZhemw48wd44pKg==

A simple example of what I'm doing now:

    private static byte[] seedValue = {
        0x2d, 0x2a, 0x2d, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x41, 0x43, 0x4f, 0x44, 0x45, 0x2d, 0x2a, 0x2d
};
private static String ALGORITHM = "AES";
private static SecretKeySpec secretKey = new SecretKeySpec(seedValue, "AES");


public static String encrypt( String data ) throws Exception {
    try {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] cipherText = cipher.doFinal(data.getBytes("UTF8"));
        String encryptedString = new String(Base64.encode(cipherText ,Base64.DEFAULT ) );
        return encryptedString;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public static String decrypt(String data) throws Exception {
    try {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] cipherText = Base64.decode(data.getBytes("UTF8"), Base64.DEFAULT);
        String decryptedString = new String(cipher.doFinal(cipherText),"UTF-8");
        return decryptedString;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

A sample of using these methods (using Jackson for read and write objects):

public static void writeSecurityInfo( String fileName, POJO pojo ){
        try{
            FileUtil.verifyFile( fileName );
            ObjectMapper mapper = new ObjectMapper();

            File file = new File( Environment.getExternalStorageDirectory(), fileName );

            try {
                pojo.setName( CryptUtils.encrypt( pojo.getName() ) );
                pojo.setAddress( CryptUtils.encrypt( pojo.getAddress() ) );
            }
            catch( Exception e ){
                e.printStackTrace();
            }

            ObjectWriter writer = mapper.writer( new DefaultPrettyPrinter() );
            writer.writeValue( file, securityPOJO );
        }
        catch( IOException e ){
            e.printStackTrace();
        }
    }

And for reading:

public static POJO readSecurityInfo( String fileName ){
        try {
            File file = new File( Environment.getExternalStorageDirectory(), fileName );

            ObjectMapper mapper = new ObjectMapper();

            InputStream inputStream = new FileInputStream( file );

            POJO pojo = mapper.readValue( inputStream, POJO.class );
            Log.e("ERROR", "BEFORE: "+ pojo.getName());
            securityPOJO.setName( CryptUtils.decrypt( pojo.getName() ) );
            Log.e("ERROR", "AFTER: "+ pojo.getName());
            pojo.setAddress( CryptUtils.decrypt( pojo.getAddress() ) );

            return pojo;

        }
        catch( Exception e ){
            e.printStackTrace();
        }
        return null;
    }

No success. Am I doing something wrong when using AES?

learner
  • 1,311
  • 3
  • 18
  • 39
  • Please [edit] your question to include a [mcve] (add the code where you call `encrypt` and `decrypt`). – Jonny Henly Mar 10 '17 at 01:21
  • my wild guess is that you are missing some padding. look at this: http://stackoverflow.com/questions/15554296/simple-java-aes-encrypt-decrypt-example – Count T Cyber Security Ltd Mar 10 '17 at 01:32
  • @CountTCyberSecurityLtd I tried the solution you provided and changed my code inserting AES/CBC/PKCS5PADDING on Cipher. Very same result. – learner Mar 10 '17 at 03:17
  • General advice: **Always use a fully qualified Cipher string.** `Cipher.getInstance("AES");` may result in different ciphers depending on the default security provider. It most likely results in `"AES/ECB/PKCS5Padding"`, but it doesn't have to be. If it changes, you'll lose compatibility between different JVMs. For reference: [Java default Crypto/AES behavior](http://stackoverflow.com/q/6258047/1816580) – Artjom B. Mar 10 '17 at 18:45
  • **Never use [ECB mode](http://crypto.stackexchange.com/q/14487/13022)**. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like [CBC](http://crypto.stackexchange.com/q/22260/13022) or [CTR](http://crypto.stackexchange.com/a/2378/13022). It is better to authenticate your ciphertexts so that attacks like a [padding oracle attack](http://crypto.stackexchange.com/q/18185/13022) are not possible. This can be done with authenticated modes like GCM or EAX, or with an [encrypt-then-MAC](http://crypto.stackexchange.com/q/202/13022) scheme. – Artjom B. Mar 10 '17 at 18:45

2 Answers2

0

I don't see any wrong in your encrypt and decrypt method. And I tested it with simple text:

try {
        String test = encrypt("My name is Nam");
        Log.e("TEST", "xxxx encrypted: "+ test);
        Log.e("TEST", "xxxx decrypted: "+ decrypt(test));
    } catch (Exception e) {
        e.printStackTrace();
    }

and the result is correct:

03-10 11:12:38.987 31251-31251/? E/TEST: xxxx encrypted: bR80WEK9pa3eicMjCZCtQg== 03-10 11:12:38.987 31251-31251/? E/TEST: xxxx decrypted: My name is Nam

So, maybe the Log you wrote is not correct:

Log.e("ERROR", "AFTER: "+ pojo.getName());

Should be:

Log.e("ERROR", "AFTER: "+ securityPOJO.getName());

or

Log.e("ERROR", "AFTER: "+ CryptUtils.decrypt( pojo.getName() ));

NOTE: I wrote a sample about encrypting/decrypting with more secure in github if you want to check it.

NamNH
  • 1,752
  • 1
  • 15
  • 37
0

There are a couple parameters to AES to keep in mind:

  • Key Length (128,256)
  • Key Value
  • Block Chaining Mode (ECB, CBC, ...)
  • CBC has an IV

I don't see in your code anything that sets the IV. Here's another Java AES example post.

Simple Java AES encrypt/decrypt example

Community
  • 1
  • 1
user3112728
  • 395
  • 1
  • 12