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.

2
  • I dream of easily-constructed rainbow tables. Commented Feb 5, 2014 at 5:24
  • @spender That's the point of the salt though. Tables have to be generated against each salt, meaning it might as well be a brute-force attack. Commented Feb 5, 2014 at 5:30

2 Answers 2

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..)

Sign up to request clarification or add additional context in comments.

5 Comments

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ç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).
@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.
@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 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.
I did a test using a JavaScript bCrypt library and a c# bCrypt library, and the hashed passwords were the same. So I can use this to create my offline login scheme. Thanks for all your help!
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

5 Comments

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.
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
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.
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.
If youre reading this in 2020+, DO NOT USE MD5. It has been cracked and it is considered unsafe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.