How to create random-salt-hash with crypto
Asked Answered
H

2

30

I want to create a salt-hash using node.js crypto lib without having to parse any hardcoded data.

What do I mean with hardcoded?

var salt, hardcodedString = "8397dhdjhjh";
crypto.createHmac('sha512', hardcodedString).update(salt).digest("base64");

Isn't there any other way how I can create a random string without using raw javascript, random functions or hardcoding something?

Regards

UPDATE

var Crypto = require('crypto')
    , mongoose = require('mongoose');

module.exports = mongoose.model('User', new mongoose.Schema({
    username: {
        type: String
        , required: true
        , index: { unique: true, sparse: true }
        , set: toLower
    },
    email: {
        type: String
        , required: true
        , index: { unique: true, sparse: true }
        , set: toLower
    },
    salt: {
        type: String
        , set: generateSalt
    },
    password: {
        type: String
        , set: encodePassword
    }
}),'Users');

function toLower(string) {
    return string.toLowerCase();
}

function generateSalt() {
    //return Math.round((new Date().valueOf() * Math.random())) + '';
    Crypto.randomBytes('256', function(err, buf) {
        if (err) throw err;
        return buf;
    });
    // return Crypto.randomBytes('256'); // fails to
}

function encodePassword(password) {
    return password;
    // TODO: setter has no access to this.salt
    //return Crypto.createHmac('sha512', salt).update(password).digest("base64");
}

function authenticate(plainPassword) {
    return encodePassword(plainPassword) === this.password;
}
Hellenism answered 17/7, 2012 at 9:58 Comment(5)
btw plain HMAC is no secure password hash. crypto.pbkdf2 with >50000 iterations is a decent choice.Dormer
^- That's called 'stretching' for those who don't know.Barrington
Very good link. It's good to find a post that contains a whole lot of info about the subject and with a good explanation.Animate
Why would you do 'stretching' by putting an actual load on the processor, instead of just delaying the response the chosen amount of time?Descant
@MikaelGrön The goal is to slow down an attacker who computes hashes on their own computer (typically on the GPU). That it slows down your own server is an unfortunate side-effect.Dormer
D
56

A quick look at the documentation turns up the crypto.randomBytes function.

var buf = crypto.randomBytes(16);

This returns a buffer containing raw bytes. If you want a string, you can use toString('base64') or toString('hex').

Dormer answered 17/7, 2012 at 11:21 Comment(4)
Why are you quoting the number? And 256 bytes is a bit long for a salt, the 256 in my post is just quotes from the example.Dormer
Sry, changed to return Crypto.randomBytes(256);.. still no salt in the mongodb document. I will check if this is a mongoose problemHellenism
Ok, set isn't triggered automaticly only if there really is a value for the attribute. I changed set: generateSalt to default: generateSalt. This works now. However is there a way to encode your salt as hex or base64?Hellenism
crypto.randomBytes(128).toString('base64');Stylite
W
1

You can do this by running on the node REPL

node
Welcome to Node.js v16.19.0.
Type ".help" for more information.
> crypto.randomBytes(16).toString('base64')
Wally answered 6/3, 2023 at 23:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.