ASP.NET Cryptography: Salt+Hash+No SSL = insecure

DJFuji

Diamond Member
Oct 18, 1999
3,643
1
76
Platform: ASP.NET
Architecture: N-Tier
Language: C#
Project Type: Web Application
Backend: SQL Sever 2000

I've traditionally used Salt + SHA1 Hash authentication but a question came up the other day that I hadn't thought of. Because we don't use SSL (clients dont support it), all passwords are being sent from the client in plain text. So even with all the security setup server side, someone can easily just sniff the packets coming from the client and gain access through that user's credentials.

I'm proposing the following solution and am wondering what other developers (Yes, you, UCJefe) think:


Have the database have the following fields:

SHA1Hash UserName
SHA1Hash Password
VarChar ServerSalt
VarChar ClientSalt


At the login page, the server would grab the clientsalt value and pass it to the client in a hidden form variable. The client javascript function would run an MD5 hash on the username and password using the salt value. It would pass this hash (h1) to the server.

The server would then take h1 and run a SHA1 hash with salt (using a different salt value??ServerSalt?) on it to get another hash (h2). This is the hash it would use to store/compare in the database.

This allows us to avoid passing plaintext passwords and yet doesn?t compromise security with plaintext passwords in the database. A dictionary attack using sniffed salt values from the client (and a good guess that we?re using MD5) would be much more difficult as the attacker would have to run his dictionary through the salt-hash and then compare each output value to the hash being sent to the server. We could also randomly generate a new client salt every time a user logs in so that the same hash would only work once.

And if an attacker from the inside decided to run a dictionary attack on the database, he?d first have to hash each common plaintext password with the client side salt, and then hash it again with the serverside salt. It would take too long to run that procedure on a huge list, and the chances of getting lucky with an administrator account are not very likely.

Does this make sense? Can anyone poke holes in my logic?
 

DJFuji

Diamond Member
Oct 18, 1999
3,643
1
76
Found a flaw in my logic when i diagrammed this out. Can't randomize the salt because the server side has no clue what the plaintext source is. Thus, it cannot generate the new hash to compare to. In a Man in the middle (MITM) scenario with someone sniffing packets over a non-secure connection, there doesnt seem to be a way around this. All he'll have to do is sniff the hash and pass that to the server as if he was the original user. Anyone see a workaround?
 

MrChad

Lifer
Aug 22, 2001
13,507
3
81
Are your clients sophisticated enough to instantiate MSXML2.XMLHTTP objects in JavaScript?
 

DJFuji

Diamond Member
Oct 18, 1999
3,643
1
76
Can i do that in js code without any user intervention? Clients are all using IE6 i think...
 

MrChad

Lifer
Aug 22, 2001
13,507
3
81
Yes. With an XMLHTTP object you can make web service (or generic HTTP) calls to your server without user intervention.

I haven't fully thought out how that might help you, but it might give you some more flexibility (you could create your own key exchange mechanism, for instance).

Text
 

DJFuji

Diamond Member
Oct 18, 1999
3,643
1
76
I read up on the XMLHTTP object and have been racking my brain but i dont think a secure solution exists that would eliminate the man in the middle attack. Even with RSA and public/private keys, he could still just sniff the encrypted usernames and passwords and send those some values up as if it were coming from the login page. Every possibly solution i can think of has a very clean and relatively simple way to circumvent. And because im using one way sha1 hashes, i can't issue a constantly changing salt value unless the server has access to plaintext usernames and passwords, which is out of the question.
 

MrChad

Lifer
Aug 22, 2001
13,507
3
81
Originally posted by: DJFuji
I read up on the XMLHTTP object and have been racking my brain but i dont think a secure solution exists that would eliminate the man in the middle attack. Even with RSA and public/private keys, he could still just sniff the encrypted usernames and passwords and send those some values up as if it were coming from the login page. Every possibly solution i can think of has a very clean and relatively simple way to circumvent. And because im using one way sha1 hashes, i can't issue a constantly changing salt value unless the server has access to plaintext usernames and passwords, which is out of the question.

I'm guessing that installing some sort of third party software on the client is not an option, correct?
 

Mark R

Diamond Member
Oct 9, 1999
8,513
16
81
I thought very long and hard about a similar problem for my own project.

In the end, SSL was the easiest solution, and also the most secure solution. You can store a salted password in the db, while still using a secure channel for transferring the password.

The problem with challenge-handshake authentication is, as you have discovered, that the server must hold a plain-text password (or a symmetrically encrypted password, together with the key), otherwise it becomes victim to a trivial replay attack.

I'm not quite clear what you mean by your clients not supporting SSL. I would have thought this was an even more basic web technology than javascript, and would expect both administrative and software support for it.

I think the talk about web service calls is really a distraction - there is a fundamental problem. If you want to use one way hashing, you have to have access to the plain text. If you can't store a password at all, and need secure remote authentication, then the only way to do it is to encrypt the communication channel with a asymmetric algorithm.

An alternative (less secure) way of doing it is to encrypt the passwords with a symmetric cipher (e.g. AES or 3DES) before storing them in the table, using a different IV for each password (storing the IV with each password). You then use a secret key hard coded into your program to retrieve the passwords. Windows does provide a secure key storage system, but I've not investigated this much - I think it's only suitable for asym. keys but you could use this to protect your application key.

As you can see, things start to get very complex yet you still don't get a good solution.
 

DJFuji

Diamond Member
Oct 18, 1999
3,643
1
76
Originally posted by: MrChad
Originally posted by: DJFuji
I read up on the XMLHTTP object and have been racking my brain but i dont think a secure solution exists that would eliminate the man in the middle attack. Even with RSA and public/private keys, he could still just sniff the encrypted usernames and passwords and send those some values up as if it were coming from the login page. Every possibly solution i can think of has a very clean and relatively simple way to circumvent. And because im using one way sha1 hashes, i can't issue a constantly changing salt value unless the server has access to plaintext usernames and passwords, which is out of the question.

I'm guessing that installing some sort of third party software on the client is not an option, correct?

That's correct.

Torpid: Clients are running through a proxy that doesnt allow SSL. I don't know the exact specifics of it, but a very small percentage of them can use it with their existing network infrastructure.

Mark,

Yeah i figured there wasnt a simple solution, or it would have been easily found on the internet. It seems that the two requirements here--one way hashing (no plain text storage) and nonsecure channels--are mutually exclusive when it comes to having a solid, secure, solution. No matter what I do, i'm always going to be vulnerable to either a MITM attack or an inside dictionary type attack.
 

torpid

Lifer
Sep 14, 2003
11,631
11
76
Also, I assume you are using forms authentication with home-brewed forms that you have full control over. Is that right?