[英]How to use Android AES encryption same as coldfusion encrypt
我們在網絡上使用coldfusion
加密方法。
Encrypt(plainText, key, "AES", "Hex")
在Android
我們通過以下方式使用 encrypt 方法:
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);
}
但是在Android
中加密的輸出不匹配,如何使用與coldfusion
encrypt
相同的Android
AES加密?
當AES
指定為算法[1]時,Coldfusion 的encrypt
默認使用AES/ECB/PKCS5
填充。 在 Java/Android 中,如果僅指定了AES
[2] ,則提供程序決定使用哪種模式和填充,但通常它也是AES/ECB/PKCS5
填充(如在我的機器上,Android 9,API 28)。 因此,算法的規范可能不是原因。 盡管如此,最好在 Java 代碼中使用完整規范AES/ECB/PKCS5Padding
而不是AES
。
可能是在 Java 代碼中錯誤地使用了來自 Coldfusion 代碼的密鑰。 在 Coldfusion 中,密鑰通常使用generateSecretKey
[3]生成,它返回 Base64 編碼的密鑰。 這意味着在 Android 代碼中,密鑰首先必須使用 Base64 解碼:
SecretKey secKey = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT), "AES");
此外,如果密鑰是為 AES-128 生成的,則不會拋出異常,因為密鑰長 16 個字節,而 Base64 編碼僅為 24 個字節,這在當前的 Android 代碼中會生成相同長度的 AES 密鑰,因為
SecretKey secKey = new SecretKeySpec(key.getBytes(), "AES");
因此,將使用 AES-192 而不是 AES-128,當然會產生不同的密文。
更新:正如評論中已經提到的,ECB 是一種不安全的操作模式,不應使用[4] 。 一個更安全的替代方案是 CBC [5] ,它在 Java/Android 和 Coldfusion [6]中都受支持。 更安全、更現代的是 GCM,這是一種經過身份驗證的加密算法,可以保證數據的真實性和機密性[7] ,如果支持,應該首選。 這里可以找到更多模式的描述[8] 。
加密需要比“AES”更多的細節,根據符號它必須是這樣的: AES/CBC/PKCS7Padding
,即它應該是:
Cipher.getInstance(transformation);
transformation
應該由[Algorithm]/[Mode]/[Padding]
,可能值的范圍取決於底層密碼。 對於 Java,它是一種:
AES/CBC/NoPadding
AES/CBC/PKCS5Padding
AES/ECB/NoPadding
AES/ECB/PKCS5Padding
DES/CBC/NoPadding
etc...
如果在這種情況下不指定模式和填充,密碼將使用默認值。
我不知道 ColdFusion 端的默認值是什么,無論如何我建議在 ColdFusion 和 Android 端使用完整的規范,例如: AES/CBC/PKCS5Padding
- 是一個很好的做法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.