Hash and check passwords in node.js using the native pbkdf2 I use the native crypto . I use the pbkdf2 and the randomBytes for salting, and the timingSafeEqual to check for the password validity when logging in.

I wrote the following functions, based on various examples and the aforementioned APIs and functions. Here is my code

(stack : node 8.11.1 + express 4.16.3 + PostgreSQL 10)

const crypto = require('crypto');

var config = {
  hashBytes: 32,
  saltBytes: 16,
  iterations: 10000,
  digest : 'SHA512'
};

const  hashPassword = (password) =&gt;{
  return new Promise((resolved, rejeted)=&gt;{
    crypto.randomBytes(config.saltBytes, (err, salt) =&gt;{
      if (err){return rejeted('Error while sign in');}
      salt = salt.toString('hex');
      crypto.pbkdf2(password, salt, config.iterations, config.hashBytes, config.digest,(err, hash) =&gt;{
        if (err) {return rejeted('Error while sign in');}
        hash = hash.toString('hex');
        const combined = [salt, hash, config.iterations, config.hashBytes, config.digest].join('$');
        resolved(combined);
      });//closes pbkdf2
    });//closes randomBytes
  })//closes Promise
}//closes hashPassword

const  verifyPassword = (password,original) =&gt;{
  return new Promise((resolved, rejeted)=&gt;{
    let hash = original.split('$')[1];
    let salt = original.split('$')[0];
    let iterations = Number(original.split('$')[2]);
    let hashBytes = Number(original.split('$')[3]);
    let digest = original.split('$')[4];
    hash = Buffer.from(hash, 'hex');

    crypto.pbkdf2(password, salt, iterations, hashBytes, digest, (err, verify) =&gt;{
      if (err){return rejeted('Error while logging in');}
      let equals = crypto.timingSafeEqual(hash, verify);
      resolved(equals);
    });
  })//closes Promise
}//closes verifyPassword

exports.hashPassword = hashPassword;
exports.verifyPassword = verifyPassword;


This works, but, here is what bothers me :


Is it ok if I save the combined from the hashPassword as text in
the DB? (column type text)
I have to convert from text back in Buffer in the verifyPassword
-- hash = Buffer.from(hash, 'hex'); part (that's because timingSafeEqual only accepts buffer). Is this ok? Does it take a lot of time?
Is using text ok, or should I use and save buffer for this?


Any suggestions? Thank you
Is it ok if I save the combined from the hashPassword as text in
  the DB? (column type text)
  


Yes, that's OK, if you use this to store password hashes. If you use it as a (encryption) key then you should avoid text, as it can be hard to destroy the result.


  
  I have to convert from text back in Buffer in the verifyPassword
  -- hash = Buffer.from(hash, 'hex'); part (timingSafeEqual only accepts buffer). Is this ok? Does it take a lot of time?
  


That's OK. Compared to PBKDF2 almost nothing takes a lot of time.


  
  Is using text ok, or should I use and save buffer for this?
  


No text is OK, see question #1.



With regards to the code, some notes:


Calling split multiple times is not a good idea, call it once and store the intermediate result.
As there are no checks on the results after the split, the hash string representation could be altered without notice (impact depends on how the code is used).
You could use just a counter to retrieve the various parts after split, and at least create the variables in order (e.g. salt before hash) - storing the hash last makes most sense to me.




I was afraid that you were implementing PBKDF2 yourself, but you seem to be correctly using the proper crypto calls.



A different idea of handling this (for you to ponder over).

Define your protocol somewhere and store a protocol version in your hash string. You could even use that to replace the salt size, iterations, hash type etc.. Then if you choose a higher iteration count you could just update your protocol version.