0

Every time I use:

BCrypt.HashPassword(password, 12)

it gives me different output. From what I've read, in order to check log-in details, I must have password itself:

BCrypt.Verify(expectedPassword , hashed);

So I'm confused: I thought I should keep in my DB only the hashes, not the passwords themselves. What am I missing ?

Tar
  • 8,529
  • 9
  • 56
  • 127
  • The user enters the password. You then hash them and compare encryptions (either directly or by using `BCrypt.Verify()`. – Adrian Wragg Sep 02 '13 at 12:27
  • @AdrianWragg, then I must have the password itself in the server ? – Tar Sep 02 '13 at 12:28
  • @Heslacher: does it matter ? – Tar Sep 02 '13 at 12:29
  • @Tal No, you should never store the password if users are logging into your system. The user provides the plain-text password each time they log in, you then hash that and compare it to the stored hash. – Adrian Wragg Sep 02 '13 at 12:29
  • @AdrianWragg, so what is the `expectedPassword` in my question ? – Tar Sep 02 '13 at 12:30
  • @Tal Without know the source of that code, I can only guess that that is the plain-text password provided by the user. See also http://stackoverflow.com/questions/11654684/verifying-a-bcrypt-hash – Adrian Wragg Sep 02 '13 at 12:31
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/36655/discussion-between-tal-and-adrian-wragg) – Tar Sep 02 '13 at 12:32
  • @Heslacher: why does it matter ? I mean, I guess `BCrypt.HashPassword(password, 12)` creates the salt internally, doesn't it ? – Tar Sep 02 '13 at 16:09

2 Answers2

1

You are 100% correct when you state:

I thought I should keep in my DB only the hashes, not the passwords themselves.

Following on from our online chat, where we clarified the issue you were querying, the general process is as follows:

  • During the process of creating (or altering) a password, the password - in plain text - comes into the system in plain text.
  • It is then hashed in-memory.
  • This hash value is then saved in the database.

Later on ...

  • When a user wishes to be authenticated, they enter their password.
  • This password comes into the system in plain text.
  • It is then hashed in-memory.
  • This hash value is then compared with the previous hash saved in the password.

The important thing to note is that, for a given hash algorithm, two identical strings will always hash to identical values, so this comparison is safe.

It is standard to allow the password to be in plain text when still in memory. It is in theory possible to encrypt it before it reaches the server (for example, it would not surprise me if there exist SHA-512 procedures written in JavaScript to hash passwords before they are submitted), but that generally is above and beyond even the most complex security requirements.

Adrian Wragg
  • 7,311
  • 3
  • 26
  • 50
0

In the code

BCrypt.Verify(expectedPassword , hashed);

You use the name "expectedPassword" and I wonder if that indicates your misconception. That is not the password you expect the user to enter. That is the plain text password they are trying to use to log in.

the 2nd parameter, hashed, is the hashed value of their "official" password (i.e. the password they registered with).

So "hashed" is stored in the database. "expectedPassword" is the password they just entered to login in. You don't store that one.

user2735420
  • 106
  • 5
  • Right, I don't store that one, but it does go through the wires/web: the user transmit it to the server, the server gets this password. That what I was confused about - I naively thought that the passwords I type never get to the other side (stored in DB or mere volatile) – Tar Sep 02 '13 at 16:03
  • Ideally you should send the plain-text password over a secure connection like shttp or ssl. – user2735420 Sep 05 '13 at 11:38
  • If that's not possible, you should hash the password before sending it. I don't know if BCryptprovides features for this. It would have to provide access to the salt on the client side so you could salt and hash. If it doesn't support this, you can use other tools, but that might require you to create the salt value manually and store it yourself in the database. (Not a big deal, but more work.) The client side would need a way to retreuve the salt and use the same hash algorithm the server side uses. – user2735420 Sep 05 '13 at 11:45