AES-256 CBC加密在Ruby / PHP中成功,但使用CryptoJS解密失败 [英] AES-256 CBC encryption succeeds in Ruby/PHP, but decryption fails with CryptoJS

查看:614
本文介绍了AES-256 CBC加密在Ruby / PHP中成功,但使用CryptoJS解密失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用AES-256 CBC加密PHP或Ruby中的字符串(使用gem 对称-encryption ),并得到相同的结果。

 <?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 ==

但是我无法用Javascript解密相同的字符串,使用 CryptoJS 。据我可以解释文档:


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



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


< blockquote>

查看我在我的jsfiddle 或这里的失败尝试:

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

var ruby​​_encrypted =BAd5fmmMTvRE4Ohvf3GpCw ==; //从Ruby加密输出
var js_encrypted = CryptoJS.AES.encrypt(Hello!,key,{iv:iv}); //测试确认CryptoJS可以解密自己的加密

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)); // 你好!

解密失败的任何想法?

解决方案

PHP和Ruby将键和IV作为二进制字符串。他们不认为它是十六进制编码的,这意味着只有64个字符键的前32个字符将被使用。 OpenSSL默认使用只需要的字节数,并且不会引发错误(在这种情况下应该是这样)。



您可能需要在CryptoJS中这样的东西:

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

所以,虽然这个密钥有256位,但安全性实际上只有128位,因为每个字符在十六进制编码字符串中只有4位。


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?

解决方案

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.

这篇关于AES-256 CBC加密在Ruby / PHP中成功,但使用CryptoJS解密失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆