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.