简体   繁体   English

PHP中的256位AES解密

[英]256-bit AES decryption in PHP

I have a working example in Java how to decrypt (256-bit AES) a string using a key. 我在Java中有一个有效的示例,该示例如何使用密钥解密(256位AES)字符串。 I need to replicate the decrypt algorithm in PHP and almost got it to work. 我需要在PHP中复制解密算法,并且几乎可以正常工作。

This is the decrypted message in Java: 这是Java中的解密消息:

CSM(MCL/KEX RCV/10001031 ORG/Comdata KYN/dsNAX6hFtKvfceT KEY/C062E276949D83554D7B5198C52C4C55ED1C65370FA71F8220538A0C3BA23172) CSM(MCL / KEX RCV / 10001031 ORG / Comdata KYN / dsNAX6hFtKvfceT KEY / C062E276949D83554D7B5198C52C4C55ED1C65370FA71F8220538A0C3BA23172)

Yet when I call the PHP method it gives 但是当我调用PHP方法时

10001031 ORG/Comdata KYN/dsNAX6hFtKvfceT KEY/C062E276949D83554D7B5198C52C4C55ED1C65370FA71F8220538A0C3BA23172) 10001031 ORG / Comdata KYN / dsNAX6hFtKvfceT KEY / C062E276949D83554D7B5198C52C4C55ED1C65370FA71F8220538A0C3BA23172)

As you can see it's not far off but the PHP method doesn't give back the first 17 characters (ie the "CSM(MCL/KEX RCV/" bit). 如您所见,它相距不远,但是PHP方法不会返回前17个字符(即“ CSM(MCL / KEX RCV /”位)。

Am I missing something trivial here? 我在这里错过了一些琐碎的事情吗?

This is the PHP class: 这是PHP类:

class OpensslAES
{
    const METHOD = 'aes-256-cbc';

    public static function encrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = openssl_random_pseudo_bytes($ivsize);

        $ciphertext = openssl_encrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );

        return $iv.$ciphertext;
    }

    public static function decrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = mb_substr($message, 0, $ivsize, '8bit');
        $ciphertext = mb_substr($message, $ivsize, null, '8bit');

        return openssl_decrypt(
            $ciphertext,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
    }
}

$class = new OpensslAES();

var_dump($class->decrypt(base64_decode("cBVlMjBttr7DKW8fhHtqJOLyMBNrgxpIJsgFFPjkA/4MWxMIudOnYzS4WuxIhUjtgGgk4CzrkJ1G60R4OWBljNTMA9ATPKh9PXe7wXAwJfE9zc698bQv4lDkXRME+q4xCb3bK/UGQ/BPVIkmRYdHcBvIHXNzGd36Nn40giigY/g="), hex2bin("SECRET_KEY_GOES_HERE")));

This is the Java class: 这是Java类:

package javaapplication1;

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

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import javax.xml.bind.DatatypeConverter;

public class JavaApplication1 {

    public static void main(String[] args) {
        byte[] ENCRYPTION_KEY = JavaApplication1.toByteArray("SECRET_KEY_GOES_HERE");
        String INPUT = new String("cBVlMjBttr7DKW8fhHtqJOLyMBNrgxpIJsgFFPjkA/4MWxMIudOnYzS4WuxIhUjtgGgk4CzrkJ1G60R4OWBljNTMA9ATPKh9PXe7wXAwJfE9zc698bQv4lDkXRME+q4xCb3bK/UGQ/BPVIkmRYdHcBvIHXNzGd36Nn40giigY/g=");

        try {
            System.out.println(JavaApplication1.decryptStringAES(INPUT, ENCRYPTION_KEY));
        } catch (Exception exception) {
            System.out.println("Error occured: " + exception);
        }
    }

    public static byte[] toByteArray(String s) {
        return DatatypeConverter.parseHexBinary(s);
    }

    public static String decryptStringAES(String input, byte[] key) throws Exception {
        byte[] IV = JavaApplication1.toByteArray("00000000000000000000000000000000");

        byte[] inputBytes = Base64.decodeBase64(input.getBytes());
        Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        decryptCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new
        IvParameterSpec(IV));
        byte[] decrypt = decryptCipher.doFinal(inputBytes);
        return new String(decrypt);
    }
}

Your Java implementation expects the IV to always be zeros, whereas your PHP implementation expects the IV to be prepended to the message. 您的Java实现期望IV始终为零,而您的PHP实现期望IV附加在消息之前。

If you want your PHP implementation to be compatible with your Java code, then you could change it like this: 如果您希望您的PHP实现与Java代码兼容,则可以这样更改:

class OpensslAES
{
    const METHOD = 'aes-256-cbc';

    public static function encrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = hex2bin('00000000000000000000000000000000');

        return openssl_encrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
    }

    public static function decrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = hex2bin('00000000000000000000000000000000');

        return openssl_decrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
    }
}

$class = new OpensslAES();

var_dump($class->decrypt(base64_decode("cBVlMjBttr7DKW8fhHtqJOLyMBNrgxpIJsgFFPjkA/4MWxMIudOnYzS4WuxIhUjtgGgk4CzrkJ1G60R4OWBljNTMA9ATPKh9PXe7wXAwJfE9zc698bQv4lDkXRME+q4xCb3bK/UGQ/BPVIkmRYdHcBvIHXNzGd36Nn40giigY/g="), hex2bin("SECRET_KEY_GOES_HERE")));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM