web-dev-qa-db-ja.com

CryptoJSとキー/ IVの長さ

AESキーとIVの長さについて質問があります。

まず第一に、例えば、私が使用している場合 薬物OpenSSL拡張と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.encrypt()の大きいサイズのキーとevenIVに渡すと、異なる出力が生成されます。だから私の質問は、なぜですか?この場合、CryptoJSライブラリとOpenSSLの違いは何ですか?

7
Damaged Organic

私はそれを持っているように見えます。

CryptoJSを使用する際にカスタムkeyIVを渡す傾向がある場合は、(CryptoJS.enc.Base64.parse()[〜 #〜] hex [〜#〜]文字列。CryptoJS.AES.encrypt())で使用されます。

この例をとると、Base64キーとiv(長さ= 22)で、CryptoJSAES-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"
_

AES-256の場合、keyの長さは32バイトです。 (取得する場合は16バイトAES-128。それ以上の場合、CryptoJSはより高いキー長に切り替わります)。それ以外の場合、復号化すると空のメッセージが表示されます。例:

_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 hexエンコード)になります。これは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.
_
14
Damaged Organic