我的应用程序中有以下加密功能:
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时,它会在发送到服务器时失败。
Key是一个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编码并发送到服务器。
发布于 2017-08-17 18:58:02
为了扭转这一局面,我发现一个错误
java.security.InvalidKeyException:非法密钥大小
在线
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);为了使其工作,我将SecretKeySpec字节数组从key.getBytes("UTF-8")更改为key.substring(0, 16).getBytes("UTF-8"),并将其使用如下:
String md5Key= "e510a13edeea112b57683d724d5d70a6";
String detailsData = "{\n" +
" \"acc_no\": \"1234691007924321\",\n" +
" \"exp\": \"07/19\",\n" +
" \"name\": \"MICHAEL XXXXXX\",\n" +
" \"type\": \"VIS\"\n" +
" }";
System.out.println(encrypt(md5Key, detailsData));我得到了这样的输出:
iufp4Rl+x/yTO7hSQBH7uU63sXAyzxgLequ3+JkFYZFz3PWwhxDC87TEC+bZ4rirgZVasrkLE1ehWWRGFV42Z29vAok+TMdwOvOettELUD3g8W2F40OyjMg4ItYkiZM+2W6Q2zf6t4sLzM6/AYqmAy1dKjPJcCQaFcnqK6mUFcM=为了在PHP中解密,我使用了以下代码,它使用key的前16个字符作为key和iv初始化器,如下所示:
$enc_data = 'iufp4Rl+x/yTO7hSQBH7uU63sXAyzxgLequ3+JkFYZFz3PWwhxDC87TEC+bZ4rirgZVasrkLE1ehWWRGFV42Z29vAok+TMdwOvOettELUD3g8W2F40OyjMg4ItYkiZM+2W6Q2zf6t4sLzM6/AYqmAy1dKjPJcCQaFcnqK6mUFcM=';
$key = 'e510a13edeea112b57683d724d5d70a6';
$key16 = substr($key, 0, 16);
$key16Hex = unpack('H*', $key16);
print openssl_decrypt($enc_data, "AES-128-CBC", $key16, 0, hex2bin($key16Hex[1]));当然,我得到了用Java加密的想要的JSON数据:
{
"acc_no": "1234691007924321",
"exp": "07/19",
"name": "MICHAEL XXXXXX",
"type": "VIS"
}奇怪的是,这一行没有错误:
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");因为我使用JDK1.8与:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;https://stackoverflow.com/questions/45649478
复制相似问题