Open mvondoyannick opened 5 years ago
Which implementation of AES are you using on Ruby? Here is the recommended implementation: https://docs.ruby-lang.org/en/2.4.0/OpenSSL/Cipher.html
btw...
CryptoJS.AES.encrypt will returns a object containing:
Usually you have to agree between platforms which operation mode (normally CBC for text), padding (normally PKCS#7 https://en.wikipedia.org/wiki/Padding_(cryptography)). And, if you are using CBC for example it'll be required to share the IV, normally as a prefix of ciphertext
Look at this:
var key = "s3cr3tk3y";
var text = "welcome to my bugs";
var result = CryptoJS.AES.encrypt(text, key);
console.log({ciphertext: result.ciphertext.toString(), iv: result.iv.toString(), salt: result.salt.toString(), key: result.key.toString()})
/* { ciphertext: '259a0a3aaab3b5505839dfb66457fb725abe6d93c12da70e3c31cfc892f56f32',
iv: 'eed7886ce38208cb78146984ad45c337',
salt: 'b8eb553554481642',
key: 'fa99058d0fd4ce1d8a697aca1ea061df0b33c86887f2771f5a29692fbcdabc21' }*/
var result = CryptoJS.AES.encrypt(text, key);
console.log({ciphertext: result.ciphertext.toString(), iv: result.iv.toString(), salt: result.salt.toString(), key: result.key.toString()})
/*{ ciphertext: '10f1688c7ffec650dcd1b75f01ac4d34cb18f5c0decbdbcc681eae018cc5b880',
iv: '9f1e0fdd32cebc2c2e38f3e176ceb558',
salt: '4228f58e6783d543',
key: 'a92f8a759d32910c6ad9be8d38d330eac7eb7ce3d3cb7d4583efbd5e9029d403' }*/
You'll never get the same result! And that is good!
But, you can define at least the iv and a key:
// I'll store the iv and key from the last encrypt
var iv = result.iv
var key = result.key
var result = CryptoJS.AES.encrypt(text, key, { iv: iv });
console.log({ciphertext: result.ciphertext.toString(), iv: result.iv.toString(), key: result.key.toString()})
/*{ ciphertext: '10f1688c7ffec650dcd1b75f01ac4d34cb18f5c0decbdbcc681eae018cc5b880',
iv: '9f1e0fdd32cebc2c2e38f3e176ceb558',
key: 'a92f8a759d32910c6ad9be8d38d330eac7eb7ce3d3cb7d4583efbd5e9029d403' }*/
// salt is no more relevant since we already has a key
You also can generate a key from a passphrase:
var pass = 's3cr3tk3y';
var salt = CryptoJS.lib.WordArray.random(128/8);
var key = CryptoJS.PBKDF2(pass, salt, {
keySize: 256/32,
iterations: 100
});
console.log(key.toString())
// 'f4840f6bddcdfa8c2c87652b7e095996b7300889d0fc10f556d503262564736f'
Remember, for a standard CryptoJS is using CBC as op mode and pad pkcs#7, look at this:
// from the same result
result.mode == CryptoJS.mode.CBC // true
result.pad == CryptoJS.pad.PKcs7 // true
I think that now you have enough information, tell me if is still there some question.
require('openssl')
pass = 's3cr3tk3y'
salt = "\xce\x57\x86\xaa\xa5\x8d\xd2\xd6\xbd\x38\x18\x88\xb4\x8e\xa7\x08"
# or create it randomly and share with the other side: OpenSSL::Random.random_bytes(16)
key = OpenSSL::KDF.pbkdf2_hmac(
pass,
salt: salt,
iterations: 100,
length: 32,
hash: 'sha1'
)
puts key.split('').map{|cc| cc.ord.to_s(16).rjust(2, '0') }.join
# f4840f6bddcdfa8c2c87652b7e095996b7300889d0fc10f556d503262564736f
# let's encrypt
iv = "\x9f\x1e\x0f\xdd\x32\xce\xbc\x2c\x2e\x38\xf3\xe1\x76\xce\xb5\x58"
# or create it randomly and share with the other side: OpenSSL::Random.random_bytes(16)
aes = OpenSSL::Cipher::Cipher.new('AES-256-CBC')
aes.encrypt
aes.iv = iv
aes.key = key
cipher = aes.update("welcome to my bugs")
cipher << aes.final
puts [cipher].pack('m')
# IiiNVyEJnRTLmNtefAy8VifEopl8st8z4dSztFhZRIg=
# You can share:
puts [(salt.bytes+iv.bytes+cipher.bytes).pack('c*')].pack('m')
# zleGqqWN0ta9OBiItI6nCJ8eD90yzrwsLjjz4XbOtVgiKI1XIQmdFMuY2158\nDLxWJ8SimXyy3zPh1LO0WFlEiA==
# and revert:
received = "zleGqqWN0ta9OBiItI6nCJ8eD90yzrwsLjjz4XbOtVgiKI1XIQmdFMuY2158\nDLxWJ8SimXyy3zPh1LO0WFlEiA==".unpack('m*')[0]
salt = received[0..16-1]
iv = received[16..32-1]
cipher = received[32..0-1]
CryptoJS = require('crypto-js');
pass = 's3cr3tk3y';
salt = CryptoJS.enc.Latin1.parse(
"\xce\x57\x86\xaa\xa5\x8d\xd2\xd6\xbd\x38\x18\x88\xb4\x8e\xa7\x08"
);
// or create it randomly and share with the other side: CryptoJS.lib.WordArray.random(16);
key = CryptoJS.PBKDF2(
pass, salt, { keySize: 256/32, iterations: 100 }
);
console.log(key.toString());
// f4840f6bddcdfa8c2c87652b7e095996b7300889d0fc10f556d503262564736f
iv = CryptoJS.enc.Latin1.parse(
"\x9f\x1e\x0f\xdd\x32\xce\xbc\x2c\x2e\x38\xf3\xe1\x76\xce\xb5\x58"
);
// or create it randomly and share with the other side: CryptoJS.lib.WordArray.random(16);
// let's encrypt
cipher = CryptoJS.AES.encrypt(
"welcome to my bugs",
key,
{ iv: CryptoJS.enc.Latin1.parse(iv) }
);
console.log(cipher.toString());
// IiiNVyEJnRTLmNtefAy8VifEopl8st8z4dSztFhZRIg=
// You can share:
console.log(
CryptoJS.enc.Hex.parse(
salt.toString()+iv.toString()+cipher.ciphertext.toString()
).toString(CryptoJS.enc.Base64)
)
// zleGqqWN0ta9OBiItI6nCJ8eD90yzrwsLjjz4XbOtViWTcTxn0LpxpQcyBaEJ9hfHVBCRxWYbx2jb7jzzX0YiQ==
// and revert:
received = CryptoJS.enc.Base64.parse(
"zleGqqWN0ta9OBiItI6nCJ8eD90yzrwsLjjz4XbOtViWTcTxn0LpxpQcyBaEJ9hfHVBCRxWYbx2jb7jzzX0YiQ=="
);
salt = CryptoJS.enc.Hex.parse(received.toString().slice(0, 32));
iv = CryptoJS.enc.Hex.parse(received.toString().slice(32, 64));
cipher = CryptoJS.enc.Hex.parse(received.toString().slice(64, -1));
Hello Leaking PassPhase key in JS can be a Security Vulnerability?
Hi, i have some challenge about CryptoJS.AES.encrypt() method. in JS
and in ruby
why result(JS) # result(ruby)? It can't generate a encryption string in JS and decrypt this string in ruby!!! can i have more info please.
thanks!