Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multipassword or multicrypt? #37

Open
passcod opened this issue Feb 26, 2017 · 5 comments

Comments

@passcod
Copy link

commented Feb 26, 2017

Prior art: MCF (Modular Crypt Format).

You've probably seen them around: $2y$10$3g2BisxTVdcTerz4UFjTCunu2DDLmyHP7q7UCE81cOhxdfIY0hHz6. Format is ${identifier}${data}. The identifier specifies the algorithm and how to parse the data field. In this case, data is further structured as: {bcrypt work factor}${22-chars salt}{checksum}.

This isn't a formal protocol proposal. I'm not quite sure whether this would be useful under the umbrella of multiformats, or given that MCF already exists and is fairly well-used. However, I have put this together:


This multiformat would provide a binary, machine-readable, centrally-defined format for password hashes. Modern password hashing has typically three parameters: the algorithm used, the salt employed, and the strength factor of the hash (usually in number of rounds).

Being able to support multiple password hash formats is important as security requirements progress. This is less an interoperability problem like multihash or multikey where the data would be used between different programs, and more an application-lifetime problem where the data would be used typically by the one program, needing to support multiple concurrent password hashing schemes as transitions occur (sometimes spanning months or years, as the new format can only be applied when the original password is available, i.e. when a user logs in).

The format might be like:

<options>[<work-factor>][<salt-length><salt>]<multihash>

where:

<options> is a byte-length bitmask indicating:
  - whether there's a strength factor
  - whether there's a salt
  - other bits reserved

<work-factor> is a varint, and only present if its bit is set in the options

<salt-length> is a varint, and <salt> is data of that length, and only present if its bit is set in the options

<multihash> is described at https://github.com/multiformats/multihash

Something that may not be optimal in this design is there is no indication of overall length, so it cannot be easily skipped over. Usually such data would be stored in a database so the concern may not be justified, but it could still be resolved.

One problem with MCF is the lack of agreed-upon algorithm list, another is the lack of formal definition of parameters. MCF is technically a two-field format: ${identifier}${data}. Implementations may do whatever they wish to further structure the {data} field, and have historically done so.

For compatibility, this multiformat may wish to define an MCF prefix, e.g. $mp$ or 0x246d 0x7024, followed by the multiformat's normal data in base64 encoding. That would allow it to be at least recognised by existing password implementations, and to co-exist with MCF-encoded password hashes during a transition period (or forever).

Links:

@hsanjuan

This comment has been minimized.

Copy link

commented Mar 1, 2017

Hey, one question, can you explain what is the strength factor and why does it need to be carried around?

@passcod

This comment has been minimized.

Copy link
Author

commented Mar 2, 2017

It's an adjustable "cost" that most modern password hashing schemes have. Usually translates to the number of rounds. You adjust it based on current or projected attack power, and based on how long a hash at that strength takes on your servers.

For example Bcrypt's is a small integer which directly translates to the number of rounds as a power of two. The current recommended value for Bcrypt is 12, that is, 2^12 rounds. On my servers, it takes ~300ms to compute a single hash, which is a good enough trade-off for usability.

You have to carry it around simply because it's one of the inputs of the hashing function. You can't verify the hash without it.

@hsanjuan

This comment has been minimized.

Copy link

commented Mar 2, 2017

Ah of course.. see I was getting confused that the MCF example you gave didn't carry a strength factor but after looking closer I realized you say:

${identifier}${salt-length}${salt}{checksum}

But for bcrypt (your example in particular) it is actually:

${identifier}${work-factor}${salt}{checksum}

where salt is 22 chars. Yes, MCF has issues. I really like this idea.

@passcod

This comment has been minimized.

Copy link
Author

commented Mar 7, 2017

I've edited the example I give to be correct as per your comments.

@indolering

This comment has been minimized.

Copy link

commented Mar 22, 2017

I think that the ability to specify arbitrary parameters is a baseline requirement for multihash. For example, Argon2 has CPU and memory work factors and FPH has "customization strings" to prevent collisions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
3 participants
You can’t perform that action at this time.