Reputation: 3818
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
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
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