簡體   English   中英

JAVA PHP加密解密

[英]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個字符將其用作keyiv初始值設定項,如下所示:

$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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM