I'm replacing a password storage system. The current implementation uses TripleDES with the key stored in plaintext in both the binaries and the config (in-case one of them is not available for some reason (DSTM)), the application decrypts the value from the database, and checks it against the plain-text value sent from the client.

I'm proposing replacing this with BCrypt (in this case, BCrypt.Net). I use the following code as an example

int workFactor = ((DateTime.Now.Year - 2000) / 2) + 6;
string salt = BCrypt.Net.BCrypt.GenerateSalt(workFactor);
Console.WriteLine("Salt: " + salt);
string password = "some test password";
string passwordHash = BCrypt.Net.BCrypt.HashPassword(password, salt);
Console.WriteLine("PW: " + passwordHash);
Console.WriteLine("Verify: " + BCrypt.Net.BCrypt.Verify(password, passwordHash));

One output of this may be

Salt: $2a$14$zhJH43uFxZU3FJ9FaFQusO
PW: $2a$14$zhJH43uFxZU3FJ9FaFQusOn7bJTsXZQgXpEGYFBIygd.8lGXIcc22
Verify: True

I noticed that there was no separator between the salt value and the password value, when Verify returned true when I didn't specify a salt.

If the salt is included in the hashed password output, is there any value in storing $2a$14$zhJH43uFxZU3FJ9FaFQusO and $2a$14$zhJH43uFxZU3FJ9FaFQusOn7bJTsXZQgXpEGYFBIygd.8lGXIcc22 separely?

I figure I would probably want to generate a new salt for the user the next time they select a password anyways.

  • 2
    Salts should not be considered private information, in that they are no more sensitive than the hashes themselves. Apr 15, 2016 at 9:59

1 Answer 1


No, as you have seen, the salt is part of the resulting hash value (the 22 characters after the cost factor). The BCrypt.Verify() function will extract the salt from the stored hash, so it is pointless to store it separately.

You can call the function with only one parameter, the library will then generate a salt and the cost factor on its own:

string passwordHash = BCrypt.HashPassword(password);
// or if you want to specify the cost factor
passwordHash = BCrypt.HashPassword(password, 12);

You must log in to answer this question.