hashcryptographypasswordsbcryptscrypt

Deterministic hash function that still has a work-factor (akin to bcrypt/scrypt)


I need to produce a hash, and would benefit from an algorithm like bcrypt with a built in work-factor. The thing is that I need this hash to be deterministic, and part of the bcrypt algorithm is generating a dynamic salt from random bytes, producing a non-deterministic output hash. This is obviously completely fine for the standard password use-case, but I have a different case for slow hashing, for which this would not be suitable.

I modified the algorithm in 2 ways, both of which service my needs completely fine, but I'm a bit nervous that I'm opening up a potential vulnerability. My potentially incorrect assumption is that the dynamic salt generated in the bcrypt algorithm is just there as a convenience, since the primary reason people use bcrypt is for password generation, they're just helping the user of the algorithm avoid shooting themselves in the foot by not having a salt, and being susceptible to things like rainbow table lookups, etc. I don't have a need for this in my particular case.

So my 2 solutions, both of which work fine, were

1.) just have the salt generation use a fixed 16 bytes rather than generating 16 random bytes. The output hash is deterministic and I can still provide a work factor when generating the salt

2.) have the salt generation accept a string which it uses to produce a deterministic 16 byte output hash (I don't know if it needs to be 16 bytes, I just didn't want to mess with the interface). The output hash is deterministic and I can still provide a work factor, and an input string as a salt.

Either of these service my use case perfectly fine, and I don't think there's anything wrong with them, but if you happen to have any deeper knowledge of this off the top of your head, I would appreciate your input.


Solution

  • For what it's worth, it seems as though the algorithm does not rely on a randomly generated salt. This does NOT mean that you should not use a salt.

    I implemented this here: https://github.com/ralusek/bcrypt-deterministic

    It allows you to provide your own arbitrary string as a salt. What it will do is hash the string you provide with SHA512, and then truncate the first 16 bytes to be used as the salt, instead of random 16 bytes. If none is provided, it falls back on using random bytes. This allows for a deterministic output for a given salt + data combination.