thinhndgc / crypto-js

Automatically exported from code.google.com/p/crypto-js
0 stars 0 forks source link

AES cipher broken binary data #126

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
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 8 years ago
>             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 8 years ago
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