dongqian6234 2018-11-20 11:39
浏览 340
已采纳

PHP AES加密JAVA到PHP - openssl_encrypt

I am using openssl_encrypt function available in PHP to get the similar result as the below java code is producing.

But it is all different. Kindly help me.

JAVA CODE

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 CODE

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 Result : ENC DATA : 4BBB37555EFFEF677CEF1B5D55843E50255F65540DF16AFB3F2A0B7B91341E54FB0432EEE2154A947DAD013E8C99822D

PHP Result : c43ba05ae04f68ae18313bc2042595fc70981e0d9421af9d232a3d17a01b5dd8dd8ce702230f6e49d918c9578f9c6944

I dont know why it is happening. Length of the string is same but result are different. How to get the similar result as in java?

  • 写回答

1条回答 默认 最新

  • doudai8783 2018-11-21 05:57
    关注

    I have solved your code by using below code Hope this may help you

        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);
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 韩国网站购物,KG支付的支付回调如何解决
  • ¥15 workstation导入ovf文件,报错,怎么解决呢?
  • ¥15 关于#c语言#的问题:构成555单稳态触发器,采用LED指示灯延时时间,对延时时间进行测量并显示(如楼道声控延时灯)需要Proteus仿真图和C语言代码
  • ¥15 workstation加载centos进入emergency模式,查看日志报警如图,怎样解决呢?
  • ¥50 如何用单纯形法寻优不能精准找不到给定的参数,并联机构误差识别,给定误差有7个?matlab
  • ¥15 workstation加载centos进入emergency模式,查看日志报警如图,没有XFS,怎样解决呢?
  • ¥15 应用商店如何检测在架应用内容是否违规?
  • ¥15 Ubuntu系统配置PX4
  • ¥50 nw.js调用activex
  • ¥15 数据库获取信息反馈出错,直接查询了ref字段并且还使用了User文档的_id而不是自己的