PHP AES 加密 JAVA 到 PHP - openssl_encrypt

PHP AES Encryption JAVA to PHP - openssl_encrypt

我正在使用 PHP 中可用的 openssl_encrypt 函数来获得与以下 java 代码生成的结果类似的结果。

但这完全不同。请帮助我。

JAVA 代码

package com.atom.echallan.security.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import com.atom.echallan.util.EChallanUtil;


public class AtomAES {

    private String password             = "8E41C78439831010F81F61C344B7BFC7";
    private String salt                 = "200000054575202";
    private static int pswdIterations   = 65536  ;
    private static int keySize          = 256;
    private final byte[] ivBytes        = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

    public AtomAES(){
        super();
    }

    public String encrypt(String plainText, String key, String merchantTxnId) throws Exception
    {
        this.password = key;
        // salt->200000054575202
        this.salt = merchantTxnId;

        return encrypt(plainText);
    }

    private String encrypt(String plainText) throws Exception {

        byte[] saltBytes = salt.getBytes("UTF-8");

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(
                password.toCharArray(),
                saltBytes,
                pswdIterations,
                keySize
                );

        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        //encrypt the message
        IvParameterSpec localIvParameterSpec = new IvParameterSpec(ivBytes);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //CBC
        cipher.init(Cipher.ENCRYPT_MODE, secret,localIvParameterSpec);

        byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));

        return  byteToHex(encryptedTextBytes);

    }

    public String decrypt(String encryptedText, String key, String merchantTxnId) throws Exception {
        this.password = key;
        this.salt = merchantTxnId;
        return decrypt(encryptedText);
    }


    private String decrypt(String encryptedText) throws Exception {

        byte[] saltBytes = salt.getBytes("UTF-8");
        byte[] encryptedTextBytes = hex2ByteArray(encryptedText);

        // Derive the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec spec = new PBEKeySpec(
                password.toCharArray(),
                saltBytes,
                pswdIterations,
                keySize
                );

        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        // Decrypt the message
        IvParameterSpec localIvParameterSpec = new IvParameterSpec(ivBytes);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//CBC
        cipher.init(Cipher.DECRYPT_MODE, secret,localIvParameterSpec);


        byte[] decryptedTextBytes = null;
        decryptedTextBytes = cipher.doFinal(encryptedTextBytes);

        return new String(decryptedTextBytes);
    }


  //Converts byte array to hexadecimal String
    private String byteToHex(byte byData[])
    {
        StringBuffer sb = new StringBuffer(byData.length * 2);

        for(int i = 0; i < byData.length; i++)
        {
            int v = byData[i] & 0xff;
            if(v < 16)
                sb.append('0');
            sb.append(Integer.toHexString(v));
        }

        return sb.toString().toUpperCase();
    }


    //Converts hexadecimal String to array of byte
    private byte[] hex2ByteArray(String sHexData)
    {
        byte rawData[] = new byte[sHexData.length() / 2];
        for(int i = 0; i < rawData.length; i++)
        {
            int index = i * 2;
            int v = Integer.parseInt(sHexData.substring(index, index + 2), 16);
            rawData[i] = (byte)v;
        }

        return rawData;
    }

    public static void main(String[] args)throws Exception{

        AtomAES aes = new AtomAES();

        String data = "mmp_txn=355106|mer_txn=M123|amt=100.0000|";
        String encData = aes.encrypt(data, EChallanUtil.ATOM_ENCRYPTION_KEY, "178");

        System.out.println("ENC DATA : " + encData);
        System.out.println("DEC DATA : " + aes.decrypt(encData, EChallanUtil.ATOM_ENCRYPTION_KEY, "178"));

    }
}

PHP 代码

class Encryption {

    public function encrypt($data, $key = "4A8A53E16C9C34EA5E77EF9FF7B2FD04", $method = "AES-256-CBC") {
        $size = openssl_cipher_iv_length($method);
        $iv = substr($key, 0, 16);
//        string openssl_pbkdf2 ( string $password , string $salt , int $key_length , int $iterations [, string $digest_algorithm ] )

        $hash = openssl_pbkdf2($key,'178','256','65536', 'sha1');
        $encrypted = openssl_encrypt($data, $method, $hash, OPENSSL_RAW_DATA, $iv);
        return bin2hex($encrypted);
    }

    public function decrypt($data, $key, $method) {
        $size = openssl_cipher_iv_length($method);
        $iv = substr($key, 0, $size);
        $decrypted = openssl_decrypt($data, $method, $key, false, $iv);
        return $decrypted;
    }

    function pkcs5_pad ($text, $blocksize) 
    { 
        $pad = $blocksize - (strlen($text) % $blocksize); 
        return $text . str_repeat(chr($pad), $pad); 
    } 

}

$text = 'mmp_txn=355106|mer_txn=M123|amt=100.0000|';
//
//$enc = new AESEncryption;
//$enc1 = new CbcCrypt;
$enc2 = new Encryption;

echo $enc2->encrypt($text);

JAVA 结果: ENC 数据:4BBB37555EFFEF677CEF1B5D55843E50255F65540DF16AFB3F2A0B7B91341E54FB0432EEE2154A947DAD013E8C99822D

PHP 结果:c43ba05ae04f68ae18313bc2042595fc70981e0d9421af9d232a3d17a01b5dd8dd8ce702230f6e49d918c9578f9c6944

我不知道为什么会这样。 字符串的长度相同但结果不同。 如何获得与 java?

类似的结果

我已经使用下面的代码解决了你的问题希望这对你有帮助

    public function encrypt($data, $key = "4A8A53E16C9C34EA5E77EF9FF7B2FD04", $method = "AES-256-CBC") {


                    $salt="178";

                    //Converting Array to bytes
                    $iv = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
                    $chars = array_map("chr", $iv);
                    $IVbytes = join($chars);


                    $salt1 = mb_convert_encoding($salt, "UTF-8"); //Encoding to UTF-8
                    $key1 = mb_convert_encoding($key, "UTF-8"); //Encoding to UTF-8

                    //SecretKeyFactory Instance of PBKDF2WithHmacSHA1 Java Equivalent
                    $hash = openssl_pbkdf2($key1,$salt1,'256','65536', 'sha1'); 

                    $encrypted = openssl_encrypt($data, $method, $hash, OPENSSL_RAW_DATA, $IVbytes);

                    return bin2hex($encrypted);

}