4

I need a way to hash passwords in C# and the ability to hash the same password in JavaScript and get the same result in order to implement an offline browsing authentication mechanisme.

I found a JavaScript version of bCrypt here: http://code.google.com/p/javascript-bcrypt/downloads/detail?name=jBCrypt-v2.2.tar.gz, and there are also C# implementations, but I don't know if they are compatible.

I need this for a web app I am developing which may be used by various people in a group in situations where a network connection may not always be available. All the data will be loaded in the web app, but each user will see only his share of the data. In order to achieve this, I need the users to authenticate themselves even when there is no network connection. I think I could do this by storing all the usernames and their password hashes (generated by the ASP.NET MVC / C# controller) in local storage. Then, when a user would enter his password, I would find its hash using JavaScript and compare it to the hashed password stored in the local storage.

The web app IS NOT handling banking information or any kind of such sensitive data, so the security requirements are minimal.

Jean-François Beauchamp
  • 5,485
  • 8
  • 43
  • 77

2 Answers2

2

Bcrypt is bcrypt. You'll need three things to use the bcrypt function: salt, key, and cost.

As long as you can supply the three required values by some means, and the libraries are not broken, then the bcrypt hash result will be the same - parameters and result may need to be converted between byte[] and a hex string or whatnot, but the hash value will be the same.

The salt and the cost is sometimes encoded into the "hash" - such as being concatenated into a single string. In this case, it should just be a simple transformation to create/extract the appropriate parameters and interchange format.


Since in this case the hash exposed and generated externally, I would use an extra round or two than that used for remote authentication - bcrypt with proper round selection is designed to mitigate brute-force/GPU attacks. (Using a different number of rounds will also make a locally brute-forced - but not real - key invalid when applied to the server.)

Also make sure to use a good salt function, such as the hash of a random number from a large domain. As per above, I'd choose a different salt than that used with the remote authentication.


Of course, since this is all client-side, a savvy user could bypass any sort of authentication. The above notes, and I do believe initial choice of bcrypt, are to ensure that the password remains secret - at least insofar the code is able to maintain. (Password reuse is a plague; and for some people, it very well might be their banking password..)

user2864740
  • 60,010
  • 15
  • 145
  • 220
  • As far as it goes with bCrypt, I'll have to try it. In the JavaScript implementation I found (see my original post), there is no cost parameter however, just a number of rounds for generating the salt, but the salt will already have been generated in C#. As far as I understand, I will have to expose this salt. I am wondering if this is a security breach. – Jean-François Beauchamp Feb 05 '14 at 17:20
  • @Jean-FrançoisBeauchamp The "cost" *is* the "number of rounds" (although the latter term is confusing because the actual number of rounds is `2^cost`). And yes, *salt is not a secret* (or rather, is no more of a secret than the hash; passwords are hashed with the very assumption that this should-be-private-data can be exposed/accessed) - the point of a salt is to prevent a the use of precomputed hashes (i.e. rainbow tables). – user2864740 Feb 05 '14 at 21:07
  • @Jean-FrançoisBeauchamp To be fair to the JS implementation, the `cost` is called `log_rounds`, and the real `rounds` is `2^log_rounds`, where "log" refers to logarithmic. – user2864740 Feb 05 '14 at 21:26
  • @Jean-FrançoisBeauchamp For a salt to be useful it must be "unique" across all the hashes and must not already have precomputed data against it. This is playing with the time/space trade-off. As such, a good choice for a salt is something like a *large random* number (e.g. 80+bits), such that it is unfeasible for enough relevant tables to be precomputed. See http://stackoverflow.com/a/5197921/2864740; although this answer suggests only 32 bits, remember the "uniqueness" is *globally* which is why I suggest using with a larger domain. Salt is also cheap. – user2864740 Feb 05 '14 at 21:29
  • 1
    I did a test using a [JavaScript bCrypt library](http://code.google.com/p/javascript-bcrypt/) and a [c# bCrypt library](http://bcrypt.codeplex.com/), and the hashed passwords were the same. So I can use this to create my offline login scheme. Thanks for all your help! – Jean-François Beauchamp Feb 07 '14 at 03:59
1

If security is minimal I would suggest using this md5 hashing library for c# http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5cryptoserviceprovider%28v=vs.110%29.aspx
from what I read of the implementation it doesnt do any salting or fancy stuff like that so any basic md5 javascript library should be compatible.
here you will find a list of javascript libraries that can compute md5s they should all work fastest MD5 Implementation in JavaScript

Community
  • 1
  • 1
clancer
  • 613
  • 4
  • 10
  • An issue with a simple md5 is that it can be brute-forced trivially as it is very fast (which is one thing bcrypt was designed to prevent). An attacker could just need to generate a list of brute-forced passwords locally (or merely use rainbow tables if there is no salt), and then test them one-by-one against the server. Of course it's not the only attack vector in such a system, but a design like this could be exploited. – user2864740 Feb 05 '14 at 05:53
  • I guess but if he is using javascript authentication its not secure anyway... and if it is then he could do the salting himself which will ensure the compatibility of these two libraries! anyway good point – clancer Feb 05 '14 at 05:57
  • Yes, indeed. However, the OPs primary concern here isn't, or should be, to prevent user access (after all, any savvy user can access the local storage), but rather to ensure that the passwords remain a secret. – user2864740 Feb 05 '14 at 06:07
  • As a matter of fact, I don't want to expose people's passwords. It is for a system that will be used by a few thousand people, and a real login is required for the first access. It is only later on that users will be able to pass tablets (it is a tablet web app) to each other during the day. That is where the offline login scheme will be useful. People will use this for their work, so there no real benefit in hacking the system. However, just in case, I want a minimum of security. – Jean-François Beauchamp Feb 05 '14 at 17:22
  • **If youre reading this in 2020+, DO NOT USE MD5. It has been cracked and it is considered unsafe.** – beggarboy Apr 08 '20 at 11:01