8

I want to generate a 256bit password for my AES encryption. When I check the password after the encryption it is different from my initial password. What am I doing wrong? Or is there some security mechanism I am not aware of?

My code:

password=Generate_key();

var encrypted = CryptoJS.AES.encrypt("Message", password);

//Those two should be the same
document.write(password+"<br>");
document.write(encrypted.key);


function Generate_key() {
    var key = "";
    var hex = "0123456789abcdef";

    for (i = 0; i < 64; i++) {
        key += hex.charAt(Math.floor(Math.random() * 16));
        //Initially this was charAt(chance.integer({min: 0, max: 15}));
    }
    return key;
}

The output is i.e.

0b05308c9a00f07044416bad7a51bacd282fc5c0c999551a4ff15c302b268b20 4df875993770411044fb35953166ee7833c32ca0741e9fec091dfa10138039e8

Is this normal or am I doing something wrong here? Thanks for help!

Ron
  • 133
  • 1
  • 1
  • 8
  • `Math.floor(Math.random() * 16)` isn't equivalent to `chance.integer({min: 0, max: 15})`. You should try `Math.round(Math.random() * 15)` – Biduleohm Apr 05 '14 at 01:16

2 Answers2

17

Encryption is done with a key, which is a set of binary bits, not a password, which implies a human-readable string.

To go from a password to a key, one can use a Password Based Key Derivation Function, such as PBKDF2. Crypto-JS already has a PBKDF2 function built-in, i.e.

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/pbkdf2.js"></script>
<script>
    var salt = CryptoJS.lib.WordArray.random(128/8);

    var key128Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32 });
    var key256Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 256/32 });
    var key512Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 512/32 });

    var key512Bits1000Iterations = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 512/32, iterations: 1000 });
</script>

In general, use as high an iteration count as you can get away with.

Salt should be a random value, as in the example above; you'll need, of course, to store that value along with the iteration count in order to get the same key given the same passphrase.

Anti-weakpasswords
  • 2,604
  • 20
  • 25
  • 3
    What if I don't need a passphrase at all? I only want to generate the key and save it somewhere. Or is the solution generating a pass phrase using my generate_key(), parse it to a key and then use aes encryption? – Ron Apr 08 '14 at 08:18
  • 1
    Then you would generate the key with the same techniques you would otherwise use to generate the salt and the IV, i.e. a cryptographically random library. In this example, you'd use CryptoJS.lib.WordArray.random for both the key and the IV. – Anti-weakpasswords Apr 09 '14 at 03:35
  • Wow, what jerks the CryptoJS developers were to specify `PBKDF2` key size in 32-bit words! – zaph Apr 07 '18 at 20:09
  • The LINK is BROKEN! – Aimal Khan May 04 '18 at 22:18
2

I found the solution. You can define your own key using var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });

So my source code is:

key=CryptoJS.enc.Hex.parse(Generate_key());
iv=CryptoJS.enc.Hex.parse(Generate_key());
var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });
Ron
  • 133
  • 1
  • 1
  • 8