最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

asp.net - Is it possible to hash a password and authenticate a user client-side? - Stack Overflow

programmeradmin3浏览0评论

I often make small websites and use the built in ASP.NET membership functionality in a SQL Server database, using the default "hashing" password storage method.

I'm wondering if there's a way to authenticate a user by hashing his password on the client and not sending it in clear text over the wire without using SSL.

I realize that this would only be applicable for users with Javascript enabled.

Or... possibly, this would be a great built-in capability for Silverlight (is this in the Silverlight roadmap?)


EDIT: I'm also looking for "degrees of security." Meaning, if there is a method that has some advantages over simply sending plaintext password, I'd like to know what they are and why.

I know there are lots of people who do small sites with logins (such as a family website or volunteering to make a site for a local cooking club) and don't see the need for purchasing SSL certificates.

I often make small websites and use the built in ASP.NET membership functionality in a SQL Server database, using the default "hashing" password storage method.

I'm wondering if there's a way to authenticate a user by hashing his password on the client and not sending it in clear text over the wire without using SSL.

I realize that this would only be applicable for users with Javascript enabled.

Or... possibly, this would be a great built-in capability for Silverlight (is this in the Silverlight roadmap?)


EDIT: I'm also looking for "degrees of security." Meaning, if there is a method that has some advantages over simply sending plaintext password, I'd like to know what they are and why.

I know there are lots of people who do small sites with logins (such as a family website or volunteering to make a site for a local cooking club) and don't see the need for purchasing SSL certificates.

Share Improve this question edited Jul 6, 2009 at 17:44 Feckmore asked Jul 6, 2009 at 16:45 FeckmoreFeckmore 4,7247 gold badges44 silver badges53 bronze badges 5
  • 3 How would this be any more secure than sending plaintext over the wire? You are still exposing data to any attackers that could be used to crack that user's account. – Adamski Commented Jul 6, 2009 at 16:49
  • As Adam says, an attacker could grab the hash sent by the user and authenticate using that same hash. – Tom Mayfield Commented Jul 6, 2009 at 16:51
  • 2 The server must provide a unique salt for each request. – Landon Kuhn Commented Jul 6, 2009 at 16:58
  • @Adamski - I'm not totally sure how this would be more secure than plaintext... thus the question. One benefit mentioned below, is that for insignificant sites (such as local cooking club) user avoids sending their password plain text, which, for many users is the same password they use to access the email address which is also their login. – Feckmore Commented Jul 6, 2009 at 17:08
  • This protects against a man in the middle stealing the password and using it later, but does not protect against a man in the middle stealing authentication and using it now. SSL, IIRC, does protect against this (holes in dns security mean this protection is flawed) by using pre-existing keys on your machine as part testing that the server is who it says it is rather than someone in the middle spoofing the server. – Brian Commented Jul 6, 2009 at 17:10
Add a comment  | 

6 Answers 6

Reset to default 6

This is possible. This is actually what Kerberos authentication does, only with a little bit of added spice. To ensure that your authentication mechanism is secure, you need the following:

  1. A common hashing algorithm on both the client and server.
  2. A one-time salt value generated on the server and shared with the client.
  3. The original password stored in a database.

To securely authenticate a user via hash code, so you avoid sending the actual password across the wire, first generate a random, single-use salt value on the server. Send this salt value to the client, and generate a hash code from the salted version of the password the user has input. Send the resulting hash code to the server, and compare it with a hash code generated from the salted version of the stored password. If the comparison fails, discard the salt, regenerate a new salt value, and repeat the process.

The reason for the single-use salt is to prevent anyone listening to the conversation from capturing the hash code of the users password, which, when you use hash code comparison, is just as good as having the password itself.

Note that you need to keep the original password around, you can't hash it once on the server and save the hash in the database. If you need to ensure that the passwords stored in your database are also secure, then you will need to encrypt them before storing them. I believe that ASP.NET membership providers do allow you to store passwords encrypted, however, if you really wish to have a secure authentication mechanism that is difficult for a hacker to crack, then I would recommend handling password storage and retrieval entirely on your own.

Finally, I should note, that such a complex password transfer mechanism should be largely unnecessary if you use SSL to encrypt your connection during authentication.

References (for those who have never heard of Kerberos or SRP):

http://en.wikipedia.org/wiki/Kerberos_(protocol) http://en.wikipedia.org/wiki/Secure_remote_password_protocol

This is a bad idea, security wise. If you send a non-ssl form that contains the hashed password, then anyone capturing traffic has all they need to login. Your javascript has to result in something that indicates success (a redirect, token passed to the server, etc). Whatever it is, the listener now can recreate that without proper authentication.

SSL was built for a reason, by people who tried a lot of other web authentication schemes. It is far safer and cheaper to get a cert than to try write your own safe authentication scheme that works without encryption.

Added for clarity:

Client side hashing alone is not safe. Say I have a form with the following inputs

<form action="signin.whatever" method="post">
<input type="text" id="txtUser">
<input type="text" id="txtPass">
<input type="hidden" id="hiddenHash">
<input type="submit" onclick="hashAndSubmit()">
</form>

where hashAndSubmit() hashes the password and puts it in hiddenHash, and blanks out the password field. If I sniff your submission and see the following fields:

txtUser:joeuser
txtPass:
hiddenHash:xxx345yz   // hash result

that's all I need as an attacker. I build a form with your user and hash value and I'm all set. The password is not necessary for a replay attack.

To get around this, you have to look at one-time salt values, or other schemes. All of which introduce more cost(don't forget developer time) and risk than SSL. Before you do something like this, ask one question...

Do I trust myself more than years and years of public testing of the SSL encryption?

You could do this, but it would be just as insecure. The problem is that someone could capture the hash and replay it (just as they could the original password). I suppose you're providing some protection against the exposure of the actual password (in case they use it on other systems), but your system will be no more secure.

You can implement your hashing algorithm client side (in javascript) and send only the user name and hash result over the wire. Note that in order for this to be secure the hash must be salted with a string provided by the server, and the string must be unique for every request. The sever still needs to check whether the hash is correct or not and authenticate the session.

At least you have to use a salt for generating the hash. Otherwise the hash value is as "valuable" as the plain password when intercepted - at least on your site.

You can send as post fields the username/realm/password hash following the HTTP Digest protocol. AFAIK there is no built-in client component nor server side component to generate/validate this so you have to do everything manually. It also requires your storage to store a specific hash format, see Storing password in tables and Digest authentication

The advantage is that you're following a well analyzed and understood authentication protocol. Don't roll your own.

发布评论

评论列表(0)

  1. 暂无评论