4

I am using Coda Hale's Ruby bcrypt library. I noticed recently that it wasn't working like I thought it worked. I had thought that the proper procedure is:

  1. Generate a salt
  2. Obtain a password
  3. Concatenate the salt and the password strings
  4. Hash them through your hashing function

But when I look at the results of the bcrypt function it appears that the salt is concatenated to the hash not the password. That is the salt concatenation happens after step #4, not before. I'm assuming Coda Hale is doing this right, but I am wondering why it behaves like this.

Here's a brief IRB session to show what's weird (to me). Notice that in the results of the hash_secret function, the first 29 chars are the same as the salt. Any information as to why this is the case would be appreciated.

My only theory is that the salt is prepended as well as embedded in the hash, which eliminates the need to store the salt in a separate DB field (essentially a record packing strategy)?

irb#1(main):004:0> password_salt = BCrypt::Engine.generate_salt
=> "$2a$10$OrKdcWORLL8Gorhy9XR3UO"
irb#1(main):005:0> password='abc'
=> "abc"
irb#1(main):006:0> BCrypt::Engine.hash_secret(password, password_salt)
=> "$2a$10$OrKdcWORLL8Gorhy9XR3UOY8Sebzq92m7r02XPitzoazPdO7tmsEO"
irb#1(main):007:0> 
Steve Midgley
  • 2,226
  • 2
  • 18
  • 20
  • 2
    It's so that the salt need not be stored separately from the hash. The salt _has_ been concatenated with the password to produce the hash, but the salt is then additionally concatenated onto the hash (along with other metadata about the hashing algorithm) so that only the single string is needed to test the hash. – Michael Berkowski Sep 18 '14 at 00:56
  • 1
    Also [How can bcrypt have built-in salts?](http://stackoverflow.com/questions/6832445/how-can-bcrypt-have-built-in-salts/6833165#6833165), which is perhaps a better resource. – Michael Berkowski Sep 18 '14 at 00:59
  • @MichaelBerkowski - agree - I wish I had seen that second question (I did search!) before asking this. I've voted to mark this as duplicate since that answers my specific question.. – Steve Midgley Sep 18 '14 at 05:59

1 Answers1

4

There is no technical reason why this is the case. If you wanted to, you could store the salt and password separately. Heck, you could make the salt public if you wanted to. I've heard some people will use the user-id as the salt to save a few bits of storage in their database.

There would be no security gain by storing hashes and salts in different fields in the same database. All that really matters is that each salt is unique in order to thwart rainbow tables.

I imagine that the creator decided to concat the two strings simply to keep the salt and hash together in a single field in the database or application. Sometimes this can be useful, for example in languages that don't support multi-value returns.

nostromo
  • 1,435
  • 2
  • 17
  • 23
  • 4
    It's also how passwords are saved on UNIX-type systems where there is a singular field for storing the hashed password. The string includes information on the hashing method, the salt, and the hash according to a fairly standard format. That way if you change hashing methods in the future, your older hashed passwords will still work. It's worth noting that without the salt and the hashing method known, it's impossible to reproduce the hash. – tadman Sep 18 '14 at 05:34