CryptoJS и длина ключа / IV

у меня есть вопрос о ключе AES и длине IV.

прежде всего, если, например, я использую наркотики и openssl_encrypt() метод, я могу ясно видеть этот ключ для 256-бит AES должно быть 32 байты, и IV выдает предупреждение, если оно отличается от 16 байт. Я могу это понять, и все в порядке.

однако, в CryptoJS библиотека длина ключа и IV расстраивает. Это пример:

var text = "test",
    key  = "us5N0PxHAWuIgb0/Qc2sh5OdWBbXGady",
    iv   = "zAvR2NI87bBx746n";

key = CryptoJS.enc.Base64.parse(key);
iv  = CryptoJS.enc.Base64.parse(iv);

crypted = CryptoJS.AES.encrypt(text, key, { iv: iv });

где ключ-это 32 байт, IV - это 16. CryptoJS требует его разбора, а после CryptoJS.enc.Base64.parse() Я получаю 48 и 24 байта соответственно. Я ожидаю, что эти значения будут усечены до требуемого 256-бит AES длина и дальнейшее расширение до n байтов не будут иметь значения, и поэтому результирующий шифрованный текст будет таким же.

но на самом деле этого не происходит. Когда я перейду к CryptoJS.AES.шифровать () ключ большего размера и даже IV, оно производит различный выход. Итак, мой вопрос: почему? В чем разница между CryptoJS библиотеки и OpenSSL в этом случае?

1 ответов


похоже, я понял.

если вы склонны пройти таможню key и IV при использовании CryptoJS убедитесь, что (при условии, что CryptoJS.enc.Base64.parse() дает HEX строка, которая используется в CryptoJS.AES.encrypt()).

возьму этот пример, с в base64 ключ и iv (длина=22), который CryptoJS шифрует как AES-256:

var message = "some_secret_message";

var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv  = "mHGFxENnZLbienLyANoi.e"; //length=22

key = CryptoJS.enc.Base64.parse(key);
//key is now e8b7b40e031300000000da247441226a, length=32
iv = CryptoJS.enc.Base64.parse(iv);
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32

var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });

var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv });
//data contains "some_secret_message"

длина key 32 байта для AES-256. (16 байт, если вы хотите сделать AES-128. Если больше, CryptoJS переключится на более высокую длину ключа). В другом случае на decrypt вы получите пустое сообщение. Пример:

var message = "some_secret_message";

var key = "6Le0DgMTAAAAANokdEEial1"; //length=23
var iv  = "mHGFxENnZLbienLyANoi.e"; //length=22

key = CryptoJS.enc.Base64.parse(key); // length = 17 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=34 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length = 16 bytes
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32 (hex encoded)

var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });

var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv });
//data contains "" - an empty string

кроме того, из того, что я вижу, только x % 8 == 0 байты такого варианта использования дают действительный результат.

длина IV должно быть 22 байта (при кодировке Base64) и при преобразовании с CryptoJS.enc.Base64.parse() вы получите 16 байт (32 закодированных шестнадцатеричных), что является максимальным для AES-256 размер блока. Все остальное будет усечено.

var message = "some_secret_message";

var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv  = "mHGFxENnZLbienLyANoi.e"; //length=22

key = CryptoJS.enc.Base64.parse(key); // length=16 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=32 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length=16 bytes
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32 (hex encoded)

var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });

var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv  = "mHGFxENnZLbienLyANoi.e123"; //length=25

key = CryptoJS.enc.Base64.parse(key); // length = 16 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=32 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length = 18 bytes
//iv is now 987185c4436764b6e27a72f2fffffffded76, length=36 (hex encoded)

var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv }); //data contains "some_secret_message", so additional "123" in IV is irrelevant.