AES-256 CBC encryption succeeds in Ruby/PHP, but decryption fails with CryptoJS

≯℡__Kan透↙ 提交于 2019-12-25 07:59:40

问题


I can AES-256 CBC encrypt a string in PHP or Ruby (using the gem symmetric-encryption) and get the same result.

<?php
openssl_encrypt(
  'Hello!', 'aes-256-cbc', '1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF', 0, '1234567890ABCDEF1234567890ABCDEF'
); // => 'BAd5fmmMTvRE4Ohvf3GpCw=='
ruby_cipher = SymmetricEncryption::Cipher.new(key: "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF", iv: "1234567890ABCDEF1234567890ABCDEF", cipher_name: 'aes-256-cbc')
ruby_cipher.encrypt("Hello!") # => "BAd5fmmMTvRE4Ohvf3GpCw=="

But I fail to decrypt the same string with Javascript, using CryptoJS. As far as I can interpret the documentation:

var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });

var decrypted = CryptoJS.AES.decrypt("Message", key, { iv: iv });

Check out my failed attempt in my jsfiddle or here:

var key            = CryptoJS.enc.Hex.parse("1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF");
var iv             = CryptoJS.enc.Hex.parse"1234567890ABCDEF1234567890ABCDEF");

var ruby_encrypted = "BAd5fmmMTvRE4Ohvf3GpCw==";                            // Output from the Ruby encryption
var js_encrypted   = CryptoJS.AES.encrypt("Hello!", key, { iv: iv });       // Test to confirm that CryptoJS can decrypt its own encrypted

var ruby_decrypted = CryptoJS.AES.decrypt(ruby_encrypted, key, { iv: iv }); // Object { words: Array[4], sigBytes: -129 }
var js_decrypted   = CryptoJS.AES.decrypt(js_encrypted, key, { iv: iv });   // Object { words: Array[4], sigBytes: 6 }

console.log(ruby_decrypted.toString(CryptoJS.enc.Utf8));                    //
console.log(js_decrypted.toString(CryptoJS.enc.Utf8));                      // Hello!

Any idea why the decryption fails?


回答1:


PHP and Ruby take the key and IV as a binary string. They don't assume that it is Hex-encoded which means that only the first 32 characters of your 64 character key will be used. OpenSSL silently uses only the number of bytes it needs and doesn't throw an error (which it should in this case).

You probably want something like this in CryptoJS:

var key    = CryptoJS.enc.Utf8.parse("1234567890ABCDEF1234567890ABCDEF");
var iv     = CryptoJS.enc.Utf8.parse("1234567890ABCDEF");

So, although this key has 256 bits in it, the security is actually only 128 bits, because each character has only 4 bit in a Hex-encoded string.



来源:https://stackoverflow.com/questions/40048164/aes-256-cbc-encryption-succeeds-in-ruby-php-but-decryption-fails-with-cryptojs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!