So, I have the encryption and decryption methods on ruby and they work fine ruby. I followed the answer from this question (How to decrypt message with CryptoJS AES. I have a working Ruby example) but it's returning an empty string.
Ruby Code
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>
The problem is that Ruby expects the key to be in binary format, not hex. So you need to do this:
#!/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
For me that prints
mdnLCY6MdwEONY1AxR/vjVKMssB+yrPsz4QMjfl6fDXxv68E0EUxtAqa4VUo
fTkjq2Hqyd48UV3dyWmEbwXw5Q==
If I put that into your HTML file (without changing any code), I get back the original message:
<!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>
So the problem is that your Ruby code produced a gibberish cyphertext. Fix the key and re-encrypt, and the JS should start working.