无法将AES 256加密代码从Java复制到PHP

时间:2018-12-11 10:34:32

标签: java php encryption aes

我们的集成合作伙伴之一向我们发送了以下Java代码,用于字符串的AES 256加密。

package com.ngcs.authcomm.service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class AESEncryption 
{
    public static final String AES_TRANSFORMATION = "AES/ECB/PKCS5Padding";
    public static final String AES_ALGORITHM = "AES";
    public static final int ENC_BITS = 256;
    public static final String CHARACTER_ENCODING = "UTF-8";

    private static Cipher ENCRYPT_CIPHER;
    private static Cipher DECRYPT_CIPHER;
    private static KeyGenerator KEYGEN; 

    static
    {
        try
        {
            ENCRYPT_CIPHER = Cipher.getInstance(AES_TRANSFORMATION);
            DECRYPT_CIPHER = Cipher.getInstance(AES_TRANSFORMATION);
            KEYGEN = KeyGenerator.getInstance(AES_ALGORITHM);
            KEYGEN.init(ENC_BITS);
        }
        catch(NoSuchAlgorithmException | NoSuchPaddingException e) 
        {
            e.printStackTrace();
        }
    }

    /**
     * This method is used to encode bytes[] to base64 string.
     * 
     * @param bytes
     *            : Bytes to encode
     * @return : Encoded Base64 String
     */

    private static String encodeBase64String(byte[] bytes) 
    {
         return new String(java.util.Base64.getEncoder().encode(bytes));
    }

    /**
    * This method is used to decode the base64 encoded string to byte[]
    * 
    * @param stringData
    *            : String to decode
    * @return : decoded String
    * @throws UnsupportedEncodingException
    */

    private static byte[] decodeBase64StringTOByte(String stringData) throws Exception 
    {
        return java.util.Base64.getDecoder().decode(stringData.getBytes(CHARACTER_ENCODING));
    }

    /**
    * This method is used to encrypt the string which is passed to it as byte[] and return base64 encoded
    * encrypted String
    * @param plainText
    *            : byte[]
    * @param secret
    *            : Key using for encrypt
    * @return : base64 encoded of encrypted string.
    * 
    */

    private static String encryptEK(byte[] plainText, byte[] secret)
    {
        try
        {
            SecretKeySpec sk = new SecretKeySpec(secret, AES_ALGORITHM);
            ENCRYPT_CIPHER.init(Cipher.ENCRYPT_MODE, sk);
            return Base64.encodeBase64String(ENCRYPT_CIPHER.doFinal(plainText));    
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return "";
        }
    }

    /**
    * This method is used to decrypt base64 encoded string using an AES 256 bit key.
    * 
    * @param plainText
    *            : plain text to decrypt
    * @param secret
    *            : key to decrypt
    * @return : Decrypted String
    * @throws IOException
    * @throws InvalidKeyException
    * @throws BadPaddingException
    * @throws IllegalBlockSizeException
    */
    public static byte[] decrypt(String plainText, byte[] secret)
                throws InvalidKeyException, IOException, IllegalBlockSizeException,
                BadPaddingException,Exception 
    {
        SecretKeySpec sk = new SecretKeySpec(secret, AES_ALGORITHM);
        DECRYPT_CIPHER.init(Cipher.DECRYPT_MODE, sk);       
        return DECRYPT_CIPHER.doFinal(Base64.decodeBase64(plainText));
    }

    public static void main(String args[])throws Exception
    {
        String encKey = ""; 

        //client asp_secret
        String asp_secret="";   


        byte[] enc_key = decrypt(encKey, asp_secret.getBytes());

        String enc_asp_secret=encryptEK(asp_secret.getBytes(), decodeBase64StringTOByte(encodeBase64String(enc_key)));

        System.out.println("asp secret encrypted:");
        System.out.println(enc_asp_secret);     
    }
}

当我使用上面的Java代码加密字符串时,出现了字符串不足的情况。

HHrR+Vck4Xx+elAvJffFFZO9rLNsvkNQQgG9aAbZhn0fB62ICvCPlE+Zqer15qSH

但是当我使用下面的php代码用相同的密钥加密相同的字符串时。

$asp_secret_key = '';
        $enc_key = '';
        $method = "AES-256-CBC";
        $key1 = mb_convert_encoding($enc_key, "UTF-8"); //Encoding to UTF-8
        //Randomly generate IV and salt
        $salt1 = random_bytes (20);
        $IVbytes = random_bytes (16);
        //SecretKeyFactory Instance of PBKDF2WithHmacSHA1 Java Equivalent
        $hash = openssl_pbkdf2($key1,$salt1,'256','65536', 'sha1');
        // Encrypt
        $encrypted = openssl_encrypt($asp_secret_key, $method, $hash, OPENSSL_RAW_DATA, $IVbytes);
//        dd($encrypted);
        // Concatenate salt, IV and encrypted text and base64-encode the result
        $result = base64_encode($salt1.$IVbytes.$encrypted);
        dd($result);

我在下面得到了另一个字符串。

mpZPNyp2EFv/j+BLb3tqo0aEHFVaeyAFvTaWw/D24kO8FlR0xfAcdn3uJhYt8mNuUbyWfwZhzEmYeCPdYzm4AeFiyYAKgKeNgPGP+Gzp5I5Esy2a

我已经尝试过Google和stackoverflow的许多答案,包括这个答案。 (Unable to replicate an encryption format from Java to PHP

但是我仍然无法获得有效的字符串,我需要将其用作另一个api中的标头元素。 任何人都可以帮助将上述java代码复制到php中。 TIA!

0 个答案:

没有答案