views:

218

answers:

2

I'm developing a new user store for my organisation and am now tackling password storage. The concepts of salting, HMAC etc are all fine with me - and want to store the users' passwords either salted and hashed, HMAC hashed, or HMAC salted and hashed - not sure what the best way will be - but in theory it won't matter as it will be able to change over time if required.

I want to have an XML & JSON service that can act as a Security Token Service for client-side apps.

I've already developed one for another system, which requires that the client double-encrypts a clear-text password using SHA1 first and then HMACSHA1 using a 128 unique key (or nonce) supplied by the server for that session only.

I'd like to repeat this technique for the new system - upgrading the algo to SHA256 (chosen since implementations are readily available for all aforementioned platforms - and it's much stronger than SHA1) - but there is a problem.

If I'm storing the password as a salted hash in the user-store, the client will need to be sent that salt in order to construct the correct hash before being HMACd with the unique session key. This would completely go against the point of using a salt in the first place. Equally, if I don't use salt for password storage, but instead use HMAC, it's still the same problem.

At the moment, the only solution I can see is to use naked SHA256 hashing for the password in the user store, so that I can then use this as a starting point on both the server and the client for a more secure salted/hmacd password transfer for the web service.

This still leaves the user store vulnerable to a dictionary attack were it ever to be accessed; and however unlikely that might be - assuming it will never happen simply doesn't sit well with me.

Greatly appreciate any input.

+1  A: 

A salt does not need to be secret - it must be unique. a salt is designed to mitigate the threat of two users having the same password and hence the same resulting hash. so you can use the user's name as the salt if you wish. a salt makes a dictionary attack much much harder because the attacker has to compute each result for every dictionary word and every possible salt.

in my opinion, i would use a password-based key derivation function (PBKDF) with a high iteration count and a salt.

http://www.bing.com/search?q=pbkdf2

Here's sample code in C#, but it's avail in most any popular framework today http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

Michael Howard-MSFT
I've just been reading around and that particular penny dropped around the same time you made this reply! I see the logic of PBKDF - there doesn't appear to be an implementation in Objective-C that could be used on the iPhone - argh.
Andras Zoltan
As a quick question - it seems that PBKDF's main purpose is to slow down dictionary attacks because it simply takes so long. Do you think an acceptable alternative be to explicitly repeat an HMAC SHA 256 encryption?
Andras Zoltan
Actually, keeping the salt a secret is important because it prevents dictionary attacks. john the ripper is an automated cracking tool which accepts a salt as a parameter, if the attacker doesn't have the salt, then they must guess randomly.
Rook
@Michael - I'm getting lost in a cryptographic nightmare maze here... Am I right in thinking that to implement this for password exchange is a case of repeating the same PBKDF on the client that will have been performed on the server?
Andras Zoltan
Yup! You have to do the same PBKDF identically at both ends.
Michael Howard-MSFT
A: 

HTTPS is the best solution for this problem.

You are throwing a lot of crypto primitives at this problem in hopes that it will go away. In general the protocol that you are proposing seems to wasteful of resources, I recommend doing research into other authentication protocols and think of ways of simplifying your protocol. Practical Cryptography is an excellent book.

The biggest problem is see is in transfer of secrets between the client and server. In order to implement this correctly you need to use a Diffie-Hellman key exchange. Luckily one has already been written in javascript:
http://enanocms.org/News:Article/2008/02/20/Diffie_Hellman_key_exchange_implemented

Another problem is that i don't see how the client can determine that its talking to the correct server. SSL uses asymmetric cryptography, backed by a PKI, which you will not be able to implement in JavaScript.

A message digest is not an encryption algorithm. It is never okay to spill a password hash, where as cipher text is meant to protect against an eavesdropping.

Spilling a password salt to an attacker will make your passwords less secure. If the attacker has a salt then they can use a dictionary to attack the password, without the salt they will have to guess randomly, making the password storage system far more robust.

Rook
I see what you mean; salting might make it harder - but not impossible. I'd started looking at implementing SRP because resorting to Https causes complications: cost issues associated with buying lots of ssl certs for potentially a lot of different domain names; and also because it complicates the use of the STS via javascript from a web page that isn't itself Https.However I think Https is possibly the best way to go for now - but I really would like to crack SRP (it's just finding implementations for each of my target client platforms!)
Andras Zoltan
@Andras I think that is a bad reason for not using ssl. Security is very expensive, except ssl is cheap, $30 for a cert is a fantastic price and its the only way to stop MITM. Even if you go with the DH Key exchange, you can't be fully protected. There isn't an alternative to ssl. At the end of the day your server will have to encrypt and decrypt traffic and that will eat resources.
Rook
Fair point - why roll your own when there is already something out there which does the job perfectly well! Time to let them upstairs know that we need to increase cost estimates :)
Andras Zoltan
@Andras, exactly you totally get it.
Rook
I don't necessarily agree with the HTTPS solution, it all depends on the threat... If the threat is snooping on the wire, then you are correct, but this does not mitigate snooping of data at rest.
Michael Howard-MSFT
@The Rook: I took your advice and have purchased Practical Cryptography as well as the forerunner to it (can't remember the bloody title now - it's at work!). Whilst I'm wary of reading them and thinking myself an expert, they do mention that SSL based on x509 certs is not a guarantee of security by any stretch of the imagination. They present a key exchange algo based on RSA, plus other password management algorithms - and I believe that with some discipline I can produce a platform independent, secure way of transferring a password in order to establish a session. Might be wrong though!
Andras Zoltan