Nav*_*mar 2 java encryption coldfusion android aes
我们在网络上使用coldfusion
加密方法。
Encrypt(plainText, key, "AES", "Hex")
Run Code Online (Sandbox Code Playgroud)
并且Android
我们以以下方式使用加密方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
但是在Android
加密的输出中不匹配,如何使用与Android
AES 相同的加密coldfusion
encrypt
?
当指定为 algorithm [1]时,Coldfusion默认encrypt
使用AES/ECB/PKCS5
填充。在 Java/Android 中,如果仅指定[2],则提供程序决定使用哪种模式和填充,但通常它也是填充(如在我的机器上,Android 9,API 28)。因此,算法的规范可能不是原因。尽管如此,最好在 Java 代码中使用完整规范而不是.AES
AES
AES/ECB/PKCS5
AES/ECB/PKCS5Padding
AES
可能是在 Java 代码中错误地使用了来自 Coldfusion 代码的密钥。在 Coldfusion 中,密钥通常是用generateSecretKey
[3]生成的,它返回 Base64 编码的密钥。这意味着在 Android 代码中,密钥首先必须使用 Base64 解码:
SecretKey secKey = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT), "AES");
Run Code Online (Sandbox Code Playgroud)
此外,如果密钥是为 AES-128 生成的,则不会抛出异常,因为密钥长 16 个字节,而 Base64 编码仅为 24 个字节,这在当前的 Android 代码中会生成相同长度的 AES 密钥,因为
SecretKey secKey = new SecretKeySpec(key.getBytes(), "AES");
Run Code Online (Sandbox Code Playgroud)
因此,将使用 AES-192 而不是 AES-128,当然会产生不同的密文。
更新:正如评论中已经提到的,ECB 是一种不安全的操作模式,不应使用[4]。一个更安全的替代方案是 CBC [5],它在 Java/Android 和 Coldfusion [6]中都受支持。更安全、更现代的是 GCM,这是一种经过身份验证的加密算法,可保证数据的真实性和机密性[7],如果支持,则应首选。这里可以找到更多模式的描述[8]。