【发布时间】:2017-02-12 20:35:32
【问题描述】:
使用 Stackoverflow 和其他网站上的许多不同示例,我设法创建了一个有效的 Java 类,用于使用 AES-128 加密和解密字符串。我还需要在 PHP 中解密和加密这些相同的字符串以允许双向通信,但是使用 PHP 的 mcrypt 我得到了与我想要实现的目标不接近的乱码和损坏的字符串。
这是 Java 源代码(封装在一个函数中):
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] keyBytes = password.getBytes("UTF-8");
digest.update(keyBytes);
keyBytes = Arrays.copyOf(digest.digest(), 16);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decryptedBytes);
例如,这将使用密钥/密码J@RMZyv7~Dyd 返回dyHuhcYI3JIQ4BssSyJ3bjE/sQCOH+fWq2EujW579BU=,并且可以使用相同的密钥解密为Dit bericht is versleuteld!。
在 PHP 中,我使用的代码要少得多,而且我不确定哪里出了问题。我使用V1gbTVCCbQK7cknbbir5Gg==作为解密密钥,也就是上面keyBytes变量的base64编码版本。
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, base64_decode("V1gbTVCCbQK7cknbbir5Gg=="), base64_decode("vdyHuhcYI3JIQ4BssSyJ3bjE/sQCOH+fWq2EujW579BU="), MCRYPT_MODE_CBC, "0000000000000000");
var_dump($decrypted);
这会产生一些损坏的字符串,我还不确定如何解决这个问题。我确信我的 PHP 实现有问题,因为我可以在 Java 中成功地对其进行加密和解密。
【问题讨论】:
-
加密的诀窍是你不想让它工作,你希望它是安全的。上述代码或您答案中的代码不安全;它不使用正确的密钥推导,不应使用零 IV。它还缺少对完整性和真实性的保护,并且 - 当用于点对点通信时 - 它也不会是机密的。
-
@zaph 好话。我会研究那些库,我确实不应该使用它。
-
@Maarten 你是对的。我仍在尝试这个,因为我没有为我的用例找到任何具体的例子,但我将看看各种开源项目如何处理我想要实现的同一件事。
标签: java php encryption aes mcrypt