简体   繁体   English

PHP(AES-256-CBC)中的Java AES / CBC / PKCS5PADDING导致不同的结果

[英]java AES/CBC/PKCS5PADDING in php (AES-256-CBC) resulting different result

Java AES/CBC/PKCS5PADDING function Java AES / CBC / PKCS5PADDING函数

public static String encrypt_key_data(String password, String message) {
    //password = 4lt0iD3biT@2O17l8
    //message = "{"key_id":"101","merchant_code":"65010A"}";

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING", "SunJCE");
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    byte[] hashedpassword = sha.digest(password.getBytes("UTF-8"));

    hashedpassword = Arrays.copyOf(hashedpassword, 16);

    SecretKeySpec key = new SecretKeySpec(hashedpassword, "AES");

    cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes("UTF-8")));
    byte[] encrypted;
    encrypted = cipher.doFinal(message.getBytes());

    return asHex(encrypted);
}

java function resulting value = 'bc26d620be9fa0d810e31e62b00a518f79524f6142b90550b9148d50a1ab94ba55671e68f6cf3ebc44dd6af12f566ee8' java函数结果值= 'bc26d620be9fa0d810e31e62b00a518f79524f6142b90550b9148d50a1ab94ba55671e68f6cf3ebc44dd6af12f566ee8'

PHP AES-256-CBC function PHP AES-256-CBC功能

function encrypt($password, $iv, $data) { 
    $password = '4lt0iD3biT@2O17l8';
    $iv = 'AAAAAAAAAAAAAAAA';
    $data = '{"key_id":"101","merchant_code":"65010A"}';
    $encodedEncryptedData = (openssl_encrypt(($data), 'AES-256-CBC', fixKey(sha1($password)), OPENSSL_RAW_DATA, $iv)); 

    print_r(bin2hex($encodedEncryptedData));
}

function fixKey($key) {
    if (strlen($key) < 32) {
        //0 pad to len 32
        return str_pad("$key", 32, "0"); 
    }

    if (strlen($key) > 32) {
        //truncate to 32 bytes  
        return substr($key, 0, 32); 
    }
    return $key;
}

php function resulting value = 'cf20379c95a41429d4097f0ef7982c72a0d25c014cc09d93ba4a111bb9c11c38bc75d6c9f16cd9cb6545dc8c31560985' php函数结果值= 'cf20379c95a41429d4097f0ef7982c72a0d25c014cc09d93ba4a111bb9c11c38bc75d6c9f16cd9cb6545dc8c31560985'

I use same password and same IV, and i have read that AES/CBC/PKCS5PADDING is equivalent with AES-256-CBC. 我使用相同的密码和相同的IV,并且我已阅读到AES / CBC / PKCS5PADDING与AES-256-CBC等效。 But why mine is resulting different result? 但是为什么我的结果不同? Please tell me where is my fault 请告诉我我的错在哪里

============================================== ==============================================

solved. 解决了。 I need to hex2bin($key) then use the key to encrypt using aes 我需要hex2bin($key)然后使用密钥使用aes进行加密

To do AES-256 you would need a 256 bit key, but you are only providing 128 bits - both in java with: 要执行AES-256,您需要一个256位密钥,但是您只提供128位-都在Java中具有:

hashedpassword = Arrays.copyOf(hashedpassword, 16);

.. and in PHP with: ..并在PHP中具有:

if (strlen($key) > 32) {
    //truncate to 32 bytes  
    return substr($key, 0, 32); 
}

as $key is a hexstring with only 4 bit per digit (4 * 32 = 128). 因为$key是一个十六进制字符串,每个数字只有4位(4 * 32 = 128)。

As Java deterts key length from the key provided, you end up with 128 bit encryption in Java. 由于Java从提供的密钥中阻止了密钥的长度,因此您最终在Java中获得了128位加密。 Exactly what PHP/Openssl ends up doing is a bit unknown as you provide conflicting information. 当您提供有冲突的信息时,PHP / Openssl最终要执行的操作确实是个未知数。 You ask for AES-256-CBC but only provides a 128 bit key. 您要求提供AES-256-CBC,但仅提供128位密钥。

Also , you should not use a simple SHA1 to derive keys from passwords. 同样 ,您不应使用简单的SHA1从密码派生密钥。 Instead use a key deriving function like pbkdf2 , or just use an actual binary key. 而是使用诸如pbkdf2之类的密钥派生函数,或者仅使用实际的二进制密钥。

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

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