Naveen Kumar
Naveen Kumar

Reputation: 3818

How to use Android AES encryption same as coldfusion encrypt

We are using coldfusion encrypt method on web.

Encrypt(plainText, key, "AES", "Hex")

And in Android we are using the encrypt method in following way:

public static String aesEncryption(String plainText, String key) {
        try {
            SecretKey secKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher aesCipher = Cipher.getInstance("AES");
            aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
            aesCipher.update(plainText.getBytes());
            byte[] cipherText = aesCipher.doFinal();
            return bytesToHex(cipherText);
        } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }


    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }

But in Android the output of encryption doesn't match, How to use Android AES encryption same as coldfusion encrypt ?

Upvotes: 2

Views: 301

Answers (2)

Topaco
Topaco

Reputation: 49251

Coldfusion's encrypt uses AES/ECB/PKCS5 padding by default when AES is specified as algorithm [1]. In Java/Android the provider decides which mode and padding is used if only AES is specified [2], but usually it's also AES/ECB/PKCS5 padding (like on my machine, Android 9, API 28). Therefore the specification of the algorithm is probably not the cause. Nevertheless, it would be better to use the full specification AES/ECB/PKCS5Padding in the Java code instead of AES.

It's possible that the key from the Coldfusion code is used incorrectly in the Java code. In Coldfusion the keys are usually generated with generateSecretKey [3] which returns the key Base64 encoded. This means that in the Android code the key would first have to be Base64 decoded with:

SecretKey secKey = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT), "AES");

Also, if the key was generated for AES-128, no exception would be thrown because a key is 16 bytes long and Base64 encoded just 24 bytes, which in the current Android code would generate an AES key of the same length because of

SecretKey secKey = new SecretKeySpec(key.getBytes(), "AES"); 

Thus, AES-192 would be used instead of AES-128, resulting in a different ciphertext of course.

Update: As already mentioned in the comments, ECB is an insecure mode of operation and shouldn't be used [4]. A more secure alternative is CBC [5], which is supported in both Java/Android and Coldfusion [6]. Even more secure and modern is GCM, an authenticated encryption algorithm that guarantees both data authenticity and confidentiality [7], which, if supported, should be preferred. Here a description of further modes can be found [8].

Upvotes: 5

Barmaley
Barmaley

Reputation: 16363

Encryption requires a bit more details than just "AES", in accordance with notation it has to be something like: AES/CBC/PKCS7Padding, namely it should be:

Cipher.getInstance(transformation);

Where transformation should be consisting [Algorithm]/[Mode]/[Padding], range of possible values depends on underlying cipher. For Java it's kind of:

AES/CBC/NoPadding
AES/CBC/PKCS5Padding
AES/ECB/NoPadding
AES/ECB/PKCS5Padding
DES/CBC/NoPadding
etc...

If you don't specify mode and padding in this case cipher will use defaults.

I have no idea what are defaults on ColdFusion side, anyway I'd suggest to use full specs both on ColdFusion and Android sides, for instance: AES/CBC/PKCS5Padding - is a good practice.

Upvotes: 3

Related Questions