Java AES / CBC / PKCS5PADDING в php (AES-256-CBC) приводит к другому результату - PullRequest
0 голосов
/ 29 октября 2018

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 = 'bc26d620be9fa0d810e31e62b00a518f79524f6142b90550b9148d50a1ab94ba55671e68f6cf3ebc44dd6af12f566ee8'

Функция 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 = 'cf20379c95a41429d4097f0ef7982c72a0d25c014cc09d93ba4a111bb9c11c38bc75d6c9f16cd9cb6545dc8c31560985'

Я использую тот же пароль и тот же IV, и я прочитал, что AES / CBC / PKCS5PADDING эквивалентен AES-256-CBC. Но почему у меня получается другой результат? Пожалуйста, скажите мне, где моя вина

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

решена. Мне нужно hex2bin($key), а затем использовать ключ для шифрования с помощью AES

1 Ответ

0 голосов
/ 29 октября 2018

Чтобы сделать AES-256 , вам потребуется 256-битный ключ, но вы предоставляете только 128 бит - оба в java с:

hashedpassword = Arrays.copyOf(hashedpassword, 16);

.. и в PHP с:

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

как $key - это шестнадцатеричная строка, содержащая только 4 бита на цифру (4 * 32 = 128).

Поскольку Java определяет длину ключа из предоставленного ключа, вы получите 128-битное шифрование в Java. Что именно делает PHP / Openssl, немного неизвестно, поскольку вы предоставляете противоречивую информацию. Вы запрашиваете AES-256-CBC , но предоставляет только 128-битный ключ.

Также , вам не следует использовать простой SHA1 для получения ключей из паролей. Вместо этого используйте функцию получения ключа, такую ​​как pbkdf2 , или просто используйте фактический двоичный ключ.

...