我使用AES-128 / ecb / PKCS5Padding + base64对数据进行ecrypting有问题。我使用以下代码加密我的数据:
String input = "{\"action\":\"getQuestion\"}";
String key = "4288f0b8060ca1b682bf795f2617cfdc";
byte[] data = input.getBytes();
byte[] encrypted = null;
byte[] keyBytes = new BigInteger(key, 16).toByteArray();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
encrypted = cipher.doFinal(data);
System.out.println(Base64.encodeBytes(encrypted));
我在加密后收到6GuKXA6FFR+yMmO8ksAEOLL5e574a5tLob7tt5IG+jk=
但我无法使用PHP函数在服务器上解密。
当我使用PHP函数加密这些数据时:
function encrypt($encrypt, $key=null)
{
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND);
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $encrypt, MCRYPT_MODE_ECB, $iv));
return $encrypted;
}
我收到6Wc3LPWvfJ7T86iG0igmdQaeZ8xs9qY419mAVWfNH+M=
,我可以使用以下PHP函数成功解密:
function decrypt($decrypt, $key=null)
{
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($decrypt), MCRYPT_MODE_ECB, $iv);
return $decrypted;
}
使用base64加密和解密没有问题;我只在使用AES-128加密时遇到问题。
答案 0 :(得分:1)
问题不在于我最初想到的IV或填充。它是如何处理PHP代码中的键的。如果您使用实际字符串4288f0b8060ca1b682bf795f2617cfdc
作为传递到mcrypt_encrypt
和mcrypt_decrypt
的密钥,那么您不使用与Java代码中相同的密钥。您需要将该十六进制字符串转换为字节。您可以通过以下方式执行此操作:
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, pack("H*", $key), base64_decode($decrypt), MCRYPT_MODE_ECB, $iv);
注意添加pack("H*", $key)
来转换值。我在PHP bin2hex
函数的注释中找到了here。这将解决当前的问题。由于PHP不执行PKCS5填充,因此在处理不同长度的数据时可能会遇到填充问题。请参阅this关于实现该缺失函数的评论。此外,由于欧洲央行不适合和数据加密的弱点,我建议调查CBC而不是ECB。
答案 1 :(得分:1)
您可以使用openssl在命令行验证Java方法的输出。如果未指定,Java会将您的IV默认为0.
The file "enc.txt" contains "6GuKXA6FFR+yMmO8ksAEOLL5e574a5tLob7tt5IG+jk=" [corrected]
运行
openssl aes-128-ecb -in enc.txt -a -K 4288f0b8060ca1b682bf795f2617cfdc -iv 0 -d
结果是:
{"action":"getQuestion"}
尝试使用$ iv值为0的mcrypt_decrypt。