4

Ok after a LOT of researching, I've settled on using bcrypt (feel free to comment) to hash and store passwords in my phonegap app.

A few days ago I stumbled upon Bcrypt.net and it seems 'good enough' to me (again, feel free to comment). So, my question is what other alternative implementations of bcrypt are available in C#? Are there any SERIOUS flaws in the implementation of Bcrypt.net?

My security model is basically going to look like this:

  1. User enters his pin/password/passphrase on the client
  2. This is sent to my .net app over secure SSL (so basically send in plaintext from the client)
  3. Use a library like bcrypt.net to hash the password and do the storage/comparison

Is there anything else that I really need to consider here?

Any help will be greatly appreciated.

reggaemahn
  • 6,272
  • 6
  • 34
  • 59

3 Answers3

3

Glad to see somebody here who did some research.

I haven't seen any good reasons why you should not use bcrypt. In general, using either bcrypt, PBKDF2 or scrypt on the server to provide a good layer of security.

As always, the devil is in the details. You certainly require SSL, if possible TLS 1.2 using AES encryption. If you cannot do this, make sure you don't allow much else than username/password + necessary HTML in your connection.

You should make a decision on the character encoding of the password. I would advice UTF-8, possibly narrowed down to printable ASCII characters. Either document the character encoding used or store it somewhere in the configuration.

Try to store all input parameters to bcrypt together with the "hashed" password. Certainly don't forget the iteration count. This makes it easier to upgrade to higher iteration count when the user enters his/her password later on. You need to generate a secure random salt of 8-16 bytes to store with the password.

In addition, you may want to apply an additional KBKDF (key based key derivation scheme) to the output of any of above PBKDF's. This makes it possible to use the output of bcyrpt for additional keys etc. KBKDF's work on data with enough entropy, so generally they take little time (e.g. use a NIST SP 800-108 compatible counter mode KDF). I guess this should be considered "expert mode".

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thank you for your detailed answer and +1 for reminding about the encoding. So (further to Vivek's answer) do you think it's worth the time and effort to do the hashing first on the client if I am DEFINITELY gonna be using SSL/TLS? – reggaemahn Jul 26 '13 at 21:53
  • @JeevanJose Yes. If you don't hash, a man-in-the-middle attack or a compromised intermediate server could see the user's plaintext password. If you hash the password: while an attacker could see (and re-use against you) a hashed password, the user's plaintext password is safe, so the user's accounts elsewhere that use the same password will not be compromised. It's not too much effort to double-hash, and the increased security is well worth it. To protect against password reuse is a much more difficult problem. :) – Xcelled Jul 26 '13 at 22:27
  • Owlstead: Why utf8 and/or narrowed ranges? .NET strings are UTF16 by default, is there a reason to go lower? The full range allows for (possibly) increased security if the user chooses it. Nothing quite irks me like finding out I can't use accented characters in a password. – Xcelled Jul 26 '13 at 22:32
  • Double hash? You mean hash on the server and on the client? – Jonathan Jul 26 '13 at 22:51
  • @Jonathan yes. Typing that over and over got old pretty fast :P – Xcelled Jul 26 '13 at 23:07
  • 2
    @JeevanJose Double hashing is pretty dubious. It protects your already protected SSL/TLS session against eavesdropping only. As an active MITM may alter the login page itself, the attacker can inject code to retrieve the password. Most people on crypto recommend against it. If you do implement double hashing, be sure to do some performance testing on the clients and make a decision based on that. UTF-8/ASCII range is the default encoding on most Runtime Environments *and* cryptographic standards. UTF-8 encodes *any* Unicode code point - just like UTF-16BE and LE. Remove the BOM in either case! – Maarten Bodewes Jul 27 '13 at 02:58
  • @owlstead totally missed that it was a webpage. From the wording in the OP, it sounded like a standalone :P but now I see the asp tag. In that case, yeah, he has more pressing concerns than double hashing. – Xcelled Jul 27 '13 at 16:54
  • @Xcelled194 It's actually a phonegap app. So, is it a webpage, well yes and no. The service that runs on the server is asp.net. Updated my question. – reggaemahn Jul 28 '13 at 08:41
  • So you have a client that should be more or less under your control. In that case you may think about client side hashing if you really don't want to know the password. Even then, don't forget that *you* control the app, so the user cannot be sure about you now knowing the password. So it is still dubious, if not a little less dubious if it has got any merit... – Maarten Bodewes Jul 28 '13 at 09:00
  • @Xcelled194 All "UTFs" can encode the same range of characters. A character unrepresentable in single byte UTF-8 will get extended to more bytes, depending on the character. Since most passwords are in latin alphabet I don't see much point in using UTF-16 or UTF-32. The difference between the three is how many bytes they use **BY DEFAULT**, where UTF-8 is by default 8-bit, UTF-16 by default is 16-bit and UTF-32 by default is 32-bit. – initramfs Aug 08 '13 at 06:48
  • @CPUTerminator I know all utfs have the same range. My comment about range was in relation to owlstead's remark: "possibly narrowed down to printable ASCII characters" – Xcelled Aug 08 '13 at 14:17
  • @Xcelled194 Oh... I'm sorry, I seem to have missed that. – initramfs Aug 08 '13 at 14:19
1

You're good with bcrypt.

Great research from a cracker: https://crackstation.net/hashing-security.htm#faq Additional verification from sophos: http://www.sophos.com/en-us/medialibrary/PDFs/other/sophossecuritythreatreport2013.pdf

bcrypt is also part of the c# libs: http://msdn.microsoft.com/en-us/library/windows/desktop/aa375383(v=vs.85).aspx

Jonathan
  • 5,736
  • 2
  • 24
  • 22
1

The major reasons for doing password hashing are:

a. Password plaintexts are not transmitted over the wire (primary).
b. Password plaintexts are never persisted on server (secondary)

So with your setup - you're not doing a. and instead relying on the SSL. I think you should still hash on client side if possible. Leaves you more margin for future changes and in general, passwords deserve higher security / protection than your content data.

Also, i don't know what kind of server apps / extensibility you may support, so again insulating the password(s) from code might still remain an additional issue.

As far as the actual algo / util for doing the hash - i don't have the security expertise :)

Vivek
  • 2,103
  • 17
  • 26
  • I agree that he MUST use bcrypt twice. In fact, I just said that in another answer... http://stackoverflow.com/a/17887940/1163742 As for the security, Bcrypt is the way to go for sure. One final note: Beware of case. If you do an insensitive compare (ie in SQL) of hashes, you will get a lot of false successes. – Xcelled Jul 26 '13 at 20:07
  • 1
    As a matter of fact I asked a question about the value of encryption on the client heree http://stackoverflow.com/a/17862000/2025666 and the idea I got from there is that encryption on the client is probably not worth the overhead. Secondly, at the moment I am writing a phonegap app, so I need to consider the strength of the mobile device for encryption. Not to mention that I would first have to find a good javascript library that supports the encryption algorithms. – reggaemahn Jul 26 '13 at 20:39
  • @JeevanJose What exactly are you encrypting? You realize that your SSL stream (which is continuous encryption) will incur just as much, if not more overhead than hashing a password, right? The password should be hashed once : when the client logs in. It's a one-time hit, but your SSL stream will be constantly running crypto transforms over its lifetime. However, any modern phone should have plenty of power for both. If I were you, I'd follow the advice of making the app the best you can, and then using a profiler to tune performance if it becomes an issue. – Xcelled Jul 26 '13 at 23:14
  • @Xcelled194 Right now I am only concerned about 'hashing' the password. What you said is exactly what I mean. If I hash on the clienct it's my hashing time + SSL encryption time. On a slow device, like many of the symbians still in use, wouldn't this take unnecessary time? – reggaemahn Jul 27 '13 at 09:39
  • @JeevanJose don't make assumptions without testing. It will take longer, it's just a question of how much longer. Do some trial runs. Also, I totally missed that you were making a webpage. In that case, you have more pressing concerns than double hashing. – Xcelled Jul 27 '13 at 16:58