在Java中使用AES-128进行加密

问题描述

问题不在于我最初想到的IV或填充。这与您如何处理PHP代码中的密钥有关。如果您使用实际的字符串4288f0b8060ca1b682bf795f2617cfdc作为传递给您的密钥mcrypt_encryptmcrypt_decrypt那么您将不会使用与Java代码中相同的密钥。您将需要将该十六进制字符串转换为字节。您可以通过以下方式执行此操作:

$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, pack("H*", $key), base64_decode($decrypt), MCRYPT_MODE_ECB, $iv);

注意添加pack("H*", $key)转换值。我在这里PHPbin2hex函数注释中发现了这一点。这将解决当前问题。由于PHP不执行PKCS5填充,因此在处理不同长度的数据时可能会遇到填充问题。见对实现该功能缺失评论。另外,由于ECB的不适合性和数据加密的弱点,我建议使用CBC而不是ECB。

解决方法

我使用AES-128 / ecb / PKCS5Padding + base64加密数据时遇到问题。我正在使用以下代码来加密我的数据:

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,MCRYPT_RAND);
   $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,base64_decode($decrypt),$iv);
   return $decrypted;
}

使用base64加密和解密不会有任何问题。我仅在使用AES-128加密时遇到问题。

猜你在找的技术问答相关文章

如何检查配对的蓝牙设备是打印机还是扫描仪(Android)
是否允许实体正文进行HTTP DELETE请求?
如何将ZipInputStream转换为InputStream?
java.util.logging Java 8中的变量
PowerMockito.doReturn返回null
Java中的RESTful调用
Swing / Java:如何正确使用getText和setText字符串
特殊字符和重音字符
Android Studio中的ndk.dir错误
错误“找不到主类”