【发布时间】:2018-01-20 19:32:26
【问题描述】:
我的应用程序中有以下加密功能:
public static String encrypt(String key, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(key.substring(0, 16).getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes("UTF-8"));
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
在 PHP 中,加密消息使用openssl_decrypt() 解码,AES-128-CBC 设置为加密方法。
但是解密总是失败,我从服务器得到的响应是它无法识别加密方法。
我无法控制服务器,因此只能在我的 Java 应用程序中对此进行任何更改。
我尝试了不同的模式,例如 AES/CBC/NoPadding,但我遇到了异常
Input Length Not Multiple of 16 bytes
现在我知道加密没有任何问题,因为我可以在我的 java 应用程序中使用AES/CBC/PKCS5Padding 进行加密和解密,但在发布到服务器时却失败了。
密钥是一个 md5 哈希。
这是我需要加密的数据示例:
{
"merchant_id": "EXX-00000001",
"user_id": "000000000001",
"code": "000200",
"details": {
"acc_no": "1234691007924321",
"exp": "07/19",
"name": "MICHAEL XXXXXX",
"type": "VIS"
}
}
只有“详细信息”值应该被加密。该代码应该是一个 md5 哈希。然后将生成的哈希用作 AES 加密的密钥。 IV 应该是散列的前 16 个字符。加密完成后,结果应以 base64 编码并发送到服务器。
【问题讨论】:
-
我认为如果您可以共享示例数据,您将发送到服务器进行解密,这将有助于重现问题。
-
首先,尝试用 PHP 和 Java 加密数据并比较结果(如果加密方式相同)。
-
您可以尝试
echo 'Hello world' | openssl enc -aes-128-cbc -k 'my-key' | base64和echo 'U2FsdGVkX1+9jifaHib7bVTXHgziXZ0jsj2CpB6H+tc=' | base64 -d | openssl enc -aes-128-cbc -d -k "my-key"命令在本地检查命令并将输出与Java输出进行比较 -
@user3718908 如果我没记错的话,只使用了前 128 位。 (如果您想在您身边至少有 2 个其他用户的情况下通知某个评论线程中的特定人员,您需要使用@:How do comment @ replies work?;我没有收到您的评论,只是再次打开问题以查看是否有是新信息)
-
我已投票结束此问题,因为您缺少协议规范并且 PHP 代码也未提供。这意味着即使我们想验证正确答案也是不可能的。
标签: java php encryption jax-rs