[英]JAVA PHP Encryption Decryption
我的應用程序中有以下加密功能:
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
現在我知道加密沒有任何問題,因為我在使用AES/CBC/PKCS5Padding
時能夠在我的java應用程序中加密和解密它在發布到服務器時失敗了。
密鑰是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中編碼並發送到服務器。
試圖扭轉這種局面,我得到了一個錯誤
java.security.InvalidKeyException:非法的密鑰大小
在線
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
為了使它工作,我將SecretKeySpec
字節數組從key.getBytes("UTF-8")
更改為key.substring(0, 16).getBytes("UTF-8")
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");
因為我使用JDK 1.8 :
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.