Reputation: 7696
The flickr authentication API is described here:
http://www.flickr.com/services/api/auth.spec.html
I have implemented something very similar for an xml-rpc based protocol, to allow signing requests without using SSL.
It basically works as follow:
For a remote function call
doSomething(foo='hello', bar='world')
I first sort argument by name, giving:
('bar', 'world'), ('foo', 'hello')
then I do string concatenation:
m = "bar:world;foo:hello"
then I append the secret key:
m = "bar:world;foo:hello;someSecret"
and finally the signature is a md5 hash of message m.
The same process is made on the server to check if the one who called the function actually knew the secret key.
For now passwords are stored in plain text on the server side. Is there a way to store hashed passwords instead ?
My guess is that the md5 hash function lacks additivity for this to be possible, but maybe it can still be achieved by some clever construction ?
Thanks,
Upvotes: 1
Views: 200
Reputation: 101139
Short answer: practically speaking, no.
Long answer: Hashing the password on either end doesn't help, as the hash of the password can now be used by the attacker to authenticate. See this section in the wikipedia article on Challenge-Response authentication for more details.
There are algorithms that allow you to verify the user's password without them providing it to you or you storing it, known as a Zero Knowledge Password Proof. One example is the Secure Remote Password Protocol. Such protocols tend to be complex, however, and implementing one yourself is complicated and probably unwise.
An easier solution is to use public key cryptography, and issue your users private keys to which you know the public part. They can then sign their messages to authenticate and identify themselves. SSL/TLS provide ready-made implementations of this.
Upvotes: 1
Reputation: 1332
First of all, I would suggest moving off of MD5 to a stronger hash function, such as the SHA2 family.
That said, nothing prevents you from using the same construction you have above, where "someSecret" is actually a hash of the password. This will cause you to do two hashing operations on the client and one on the server, while keeping the hashed password in storage.
I would also second using an actual HMAC instead of doing your own construction. Also, instead of hashing the password, use at least PBKDF2 with a reasonable amount of iterations. Therefore you will get your client to do HMAC(data, PBKDF2(someSecret, 1000)) and the server will just store PBKDF2(someSecret, 1000), then do HMAC(data, storedResult).
Upvotes: 1