【问题标题】:CryptoJS is not working with IV and key, but it works in RubyCryptoJS 不适用于 IV 和密钥,但它适用于 Ruby
【发布时间】:2017-01-13 19:49:21
【问题描述】:

所以,我有 ruby​​ 的加密和解密方法,它们可以很好地工作 ruby​​。我按照this question (How to decrypt message with CryptoJS AES. I have a working Ruby example) 的回答,但它返回一个空字符串。

Ruby 代码

def load_vars
        @key = "2e35f242a46d67eeb74aabc37d5e5d05"
        @algorithm = "aes-128-cbc"
    end

    def encryption(data)
        begin
            key = @key
            aes = OpenSSL::Cipher.new(@algorithm)
            aes.encrypt()
            aes.key = key
            iv_value = aes.random_iv
            aes.iv = iv_value
            crypt = aes.update(data) + aes.final()
            crypt_string = (Base64.encode64(iv_value + crypt))
            return crypt_string
        end
    end

    def decryption(data)
        begin
            key = @key
            aes = OpenSSL::Cipher.new(@algorithm)
            iv_value = Base64.decode64(data)[0...16]
            data_value = Base64.decode64(data)[16..-1]
            aes.decrypt
            aes.key = @key
            aes.iv = iv_value
            results = aes.update(data_value) + aes.final
            return results
        end
    end

HTML JSFIDDLE

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>

<script>        
    data = "wlkAKa4ps+Xizx4VIdUSp43yfQvOmt9FNlVTQ1ANsCU=\n"; // The data received from the ruby encryption method
    key = "2e35f242a46d67eeb74aabc37d5e5d05";

    // Decode the base64 data so we can separate iv and crypt text.
    var rawData = atob(data);
    var iv = rawData.substring(0,16);
    var crypttext = rawData.substring(16);

    // Decrypt...
    var plaintextArray = CryptoJS.AES.decrypt(
      { ciphertext: CryptoJS.enc.Latin1.parse(crypttext) },
      CryptoJS.enc.Hex.parse(key),
      { iv: CryptoJS.enc.Latin1.parse(iv) }
    );

    console.log(CryptoJS.enc.Latin1.stringify(plaintextArray));
</script>

【问题讨论】:

  • 您的 javascript 代码是正确的,因为它适用于链接的 data 值,因此问题出在 Ruby 代码中。我认为问题出在key 参数中。加密时,您直接传递十六进制,但您应该提供解码后的值。你可以试试aes.key = key.scan(/../).collect{ |x| x.hex }.pack('c*')(从你的链接中提取)。恐怕我不能更具体,因为我不知道 Ruby
  • 能否提供生成加密数据的原始(明文)数据:data = "wlkAKa4ps+Xizx4VIdUSp43yfQvOmt9FNlVTQ1ANsCU=\n";?有了原始数据,我们可以实现生成它的加密方法,然后从那里调试。
  • @SuthanBala,您是否尝试过使用我提供的将 HEX 密钥转换为字节的代码?
  • @pedrofb 是的,我做到了,没有运气。
  • 请按照我的建议,包括原始文本和使用十六进制密钥转换的加密数据

标签: javascript ruby-on-rails cryptography aes cryptojs


【解决方案1】:

问题在于 Ruby 期望密钥是二进制格式,而不是十六进制。所以你需要这样做:

#!/usr/bin/env ruby

require 'openssl'
require 'base64'

data = "When in Rome do as the Romans do"
key = "2e35f242a46d67eeb74aabc37d5e5d05"
aes = OpenSSL::Cipher.new("aes-128-cbc")
aes.encrypt()
aes.key = key.scan(/../).collect{|x| x.hex}.pack("c*")
iv_value = aes.random_iv
aes.iv = iv_value
crypt = aes.update(data) + aes.final()
crypt_string = (Base64.encode64(iv_value + crypt))
puts crypt_string

对于打印的我来说

mdnLCY6MdwEONY1AxR/vjVKMssB+yrPsz4QMjfl6fDXxv68E0EUxtAqa4VUo
fTkjq2Hqyd48UV3dyWmEbwXw5Q==

如果我将它放入您的 HTML 文件中(不更改任何代码),我会返回原始消息:

<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>

<script>        
data = "mdnLCY6MdwEONY1AxR/vjVKMssB+yrPsz4QMjfl6fDXxv68E0EUxtAqa4VUo\nfTkjq2Hqyd48UV3dyWmEbwXw5Q==\n";
key = "2e35f242a46d67eeb74aabc37d5e5d05";

var rawData = atob(data);
var iv = rawData.substring(0,16);
var crypttext = rawData.substring(16);

// Decrypt...
var plaintextArray = CryptoJS.AES.decrypt(
  { ciphertext: CryptoJS.enc.Latin1.parse(crypttext) },
  CryptoJS.enc.Hex.parse(key),
  { iv: CryptoJS.enc.Latin1.parse(iv) }
);

console.log(plaintextArray);
console.log(CryptoJS.enc.Latin1.stringify(plaintextArray));
</script>
</head>
<body>
</body>
</html>

所以问题在于您的 Ruby 代码生成了乱码密文。修复密钥并重新加密,JS应该开始工作了。

【讨论】:

  • 这和我的评论不一样?
  • 现在可以在 JavaScript 中使用,谢谢。但是,这破坏了之前工作的 ruby​​ 中的解密方法。
  • 要修复 Ruby 解密,您还必须更改在那里设置密钥的方式(使其与加密端匹配)。
猜你喜欢
  • 2020-03-18
  • 2013-11-15
  • 1970-01-01
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多