Skip to content

feature request: defining work in terms of time (not rounds) #787

Open
@phiferd

Description

@phiferd

As I understand it, the current best practice to selecting the right number of rounds to use is to figure out how much time you're willing to spend computing password hashes, test to see how many rounds that would be, and then use that many rounds until, say, next year, when you need to reevaluate. Would it be better to allow the work parameter to be sent in units of time?

It seems it would be pretty easy to add a new hash method that would accept a minimum time (maybe in addition to a minimum work factor, as a sanity check) to produce an encrypted value. Here's the pseudo code around what I think would be the key changes (https://github.com/kelektiv/node.bcrypt.js/blob/master/src/bcrypt.cc#L235):

 thash(pwd, minTimeMillis, minLogRounds, seed) 
    // do the usual setup as in hash()
    // "seed" is the only portion of the normal salt that is needed for this, I think 
    ...

    done = false;
    log_rounds = minLogRounds;
    startTimeMillis = now
    while (!done) {
        for (k = 0; k < rounds; k++) {
		// do the normal expand state stuff here
	}
        elapsedTimeMillis = now - startTimeMillis;
        if (elapsedTimeMillis < minTimeMillis) 
            rounds = rounds * 2;
            log_rounds = log_rounds + 1;
        else 
            done = true;
   }
   ...

That way, you could use

const hashed = await bcrypt.thash(plainTextPassword, minTimeMillis, minLogRounds);

where minMillis is less likely to need to be periodically re-evaluated and devs can more easily think about how much time they can spare to do the hashing. Also, there may be reasonable default settings for both parameters, which would allow:

const hashed = await bcrypt.thash(plainTextPassword);

The seed parameter could be generated automatically if it's not provided, just like the full salt is generated automatically right now.

The output would look just like the output of hash and would contain all of the usual information (version, seed, logr, encrypted), so there would be no issue with compatibility.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions