CryptoJS 不适用于 IV 和密钥,但它适用于 Ruby
CryptoJS is not working with IV and key, but it works in Ruby
所以,我在 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>
问题是 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 代码产生了乱码密文。修复密钥和 re-encrypt,JS 应该开始工作了。
所以,我在 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>
问题是 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 代码产生了乱码密文。修复密钥和 re-encrypt,JS 应该开始工作了。