AES cipher broken binary data
Opened this issue · 2 comments
GoogleCodeExporter commented
Hi, I'm using CryptoJS for migrate a node.js application to native-javascript
(web) application.
I need cipher binary data without encoding, and the result of the decipher isnt
the same that the original one.
Example code:
cipherSync: function (algorithm,data, key) {
// var data = new Buffer([0,177,244,30]);
// var data = new Buffer("Hola múndo",'utf-8');
console.log("Go to ecnrypt " + algorithm);
console.log("Data: " + data.toString('hex'));
console.log("with key:" + key.toString('hex'));
var enc = "";
var bdata = data.toString('binary');
var bkey = key.toString('binary');
switch (algorithm) {
case 'aes256':
console.log("AES");
enc = CryptoJS.AES.encrypt(bdata,bkey);
console.log("OK AES");
break;
// ...
}
console.log("RES: " + enc.toString());
return new Buffer(enc.toString(), 'base64');
},
decipherSync: function (algorithm,data, key) {
var enc = "";
var bdata = data.toString('base64');
var bkey = key.toString('binary');
console.log("Decryp with key:" + key.toString('hex'));
console.log("Data: ", data.toString('base64'));
switch (algorithm) {
case 'aes256':
enc = CryptoJS.AES.decrypt(bdata,bkey);
break;
// ...
}
console.log("res: " + enc.toString());
console.log(asBuffer(enc).toString('hex'));
return asBuffer(enc);
},
If I force to cipher "Hola mundo" or "Holá mundo" (a utf-8 text), the cipher
works well, the result of the console login is:
-> to cipher:
"Go to ecnrypt aes256" crypto-js.js:32
"Data: 486f6c61206dc3ba6e646f" crypto-js.js:33
"with key:d9c43731......
"AES" crypto-js.js:43
"OK AES" crypto-js.js:45
"RES: U2FsdGVkX1+jiYkrj2TLMmq991w+jXW+fARBXu7BbpI=" crypto-js.js:58
"si"
-> to Decipher:
"Decryp with key:d9c4.....
"Data: " "U2FsdGVkX1+jiYkrj2TLMmq991w+jXW+fARBXu7BbpI=" crypto-js.js:70
"res: 486f6c61206dc383c2ba6e646f" crypto-js.js:88
"486f6c61206dc383c2ba6e646f"
This works ok, but if I send a binary chunk (the new Buffer([0,177,244,30])):
-> To cipher:
"Go to ecnrypt aes256" crypto-js.js:32
"Data: 00b1f41e" crypto-js.js:33
"with key:e1dd5...
"AES" crypto-js.js:43
"OK AES" crypto-js.js:45
"RES: U2FsdGVkX18fUZleU2y1P4NSKf+8Do+22rBwWrdw/BI=" crypto-js.js:58
"si"
-> To decipher:
"Decryp with key:e1dd557...
"Data: " "U2FsdGVkX18fUZleU2y1P4NSKf+8Do+22rBwWrdw/BI=" crypto-js.js:70
"res: 00c2b1c3b41e" crypto-js.js:88
"00c2b1c3b41e"
The result starts and ends with the same original bytes, but replace b1:f4 by
c2b1:c3b4
Original issue reported on code.google.com by Tios...@gmail.com
on 10 Apr 2014 at 8:23
GoogleCodeExporter commented
> var bdata = data.toString('binary');
> var bkey = key.toString('binary');
> // ...
enc = CryptoJS.AES.encrypt(bdata,bkey);
You're passing both the data and the key as strings. CryptoJS will convert the
data string to bytes using UTF-8, and the key string is treated as a passphrase
from which to derive an actual key bytes. If you want CryptoJS to know that
this is raw binary data, then you need to convert it to a
CryptoJS.lib.WordArray object. Probably the simplest way to do that is:
CryptoJS.AES.encrypt(
CryptoJS.enc.Latin1.parse(bdata),
CryptoJS.enc.Latin1.parse(bkey)
)
Note that when you pass a literal key, then you also need to pass a literal IV.
Original comment by Jeff.Mott.OR
on 10 Apr 2014 at 9:30
GoogleCodeExporter commented
Ok, right!
Another little question, I use the cryto.createCipher() of node.js, this method
admites 2 arguments (algorithm and password).
I use a PBKDF2 key generated with the password and a salt. But with the same
key generated using as password, CryptoJs and node crypto lib are not
compatible.
I think this is because each library generate the key/iv with different
algorithms.
If I want to use my owns generated key/iv, what sizes would be the expected?
BTW: If I use WordArray as phrasepassword this doesn't works.
Sorry my poor english :D
Original comment by Tios...@gmail.com
on 11 Apr 2014 at 9:39