I'm trying to create a strong key for encrypting some data using AES-256 for fun and practice. For my own practice, I want to make this as strong as possible, I don't care how long it takes to complete.

I got some advice from 1Password white paper and therefore I want to use 2 secret keys. The master password and a random generated 32-byte string. The master password and the secret key will always be kept on the client side and never transferred to the server. Let me know how I can make this stronger.

The steps go like this:

1) Create a 32-byte salt.

2) Create a 32-byte secret key

3) Using PBKDF2-HMAC-SHA512 with 100,000 iterations, create a key using the password and the salt.

4) XOR the key and the secret key to create the key to be used to encrypt using AES-256.

 crypto.randomBytes(32, function(err, salt) {
  crypto.randomBytes(32, function(err, secretKey) {
    crypto.pbkdf2(password, salt, 100000, 32, "sha512", (err, derivedKey) => {
      var a = derivedKey;
      var b = secretKey;

      if (!Buffer.isBuffer(a)) a = new Buffer(a)
      if (!Buffer.isBuffer(b)) b = new Buffer(b)
      var res = []
      if (a.length > b.length) {
        for (var i = 0; i < b.length; i++) {
          res.push(a[i] ^ b[i])
      } else {
      for (var i = 0; i < a.length; i++) {
        res.push(a[i] ^ b[i])

      var aes256Key = new Buffer(res).toString('hex');

This is going to be client-side Javascript, run inside a React-Native application.

I just want it to be looked over to make sure I'm using strong methods as well as correct key lengths for AES 256.

  • 2
    $\begingroup$ I want to make this as strong as possible you'll want to do it in a language other than javascript. Aside from that, it's not really clear what your question is. $\endgroup$ – Ella Rose Jun 10 '18 at 15:17
  • $\begingroup$ This is going to be client side Javascript, run inside a React-Native application. I just want it to be looked over to make sure i'm using strong methods as well as correct key lengths for AES 256. $\endgroup$ – Chrisgozd Jun 10 '18 at 15:22
  • $\begingroup$ Concerning closure: This appears to be a question about the security of a design using code to illustrate it, not a question about how to implement the design, and as such there's no reason to treat it as off-topic programming help. $\endgroup$ – Squeamish Ossifrage Jun 11 '18 at 1:04

This is largely a reasonable strategy given the tools at hand. The salt need only be 16 bytes to thwart multi-target attacks, though using a 32-byte salt doesn't hurt. You will presumably want to store the secret and the salt separately, so that it requires both of them to confirm a guess about the password; otherwise there's no sense in having a separate secret.

Rather than use PBKDF2-HMAC-SHA512 with exactly 100 000 iterations, you should estimate how long you are willing to wait on the slowest device you care about, and use as many iterations as that device can compute in that time. Even better, if you have a large memory available and access to scrypt or argon2, you should use one of those to exploit the memory available in order to raise the attacker's costs in a different dimension.

The more time you spend, the more joules of energy the attacker must spend to try each guess. But the attacker can try guesses in parallel. The more memory you spend, the more die area the attacker must spend on memory instead of parallelism.

N.B.: This is only about the cryptography. I am not commenting on the quality of your JavaScript code; there is CodeReview.SE for code reviews.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.