我可以存储哈希密码吗?

时间:2011-07-05 13:40:21

标签: api authentication hash cryptography

此处描述了flickr身份验证API:

http://www.flickr.com/services/api/auth.spec.html

我已经为基于xml-rpc的协议实现了非常类似的功能,允许在不使用SSL的情况下签名请求。

它基本上如下:

对于远程函数调用

doSomething(foo='hello', bar='world')

我首先按名称对参数进行排序,给出:

('bar', 'world'), ('foo', 'hello')

然后我进行字符串连接:

 m = "bar:world;foo:hello"

然后我附上了密钥:

 m = "bar:world;foo:hello;someSecret"

最后签名是消息m的md5散列。

在服务器上进行相同的过程以检查调用该函数的人是否确实知道该密钥。

现在密码以明文形式存储在服务器端。有没有办法存储散列密码?

我的猜测是md5哈希函数缺乏可加性,但也许它仍然可以通过一些聪明的构造来实现?

谢谢,

2 个答案:

答案 0 :(得分:1)

首先,我建议将MD5转移到更强大的哈希函数,例如SHA2系列。

也就是说,没有什么能阻止你使用上面的相同结构,其中“someSecret”实际上是密码的哈希值。这将使您在客户端和服务器上执行两次哈希操作,同时将哈希密码保存在存储中。

我还会使用实际的HMAC而不是自己构建。此外,不使用哈希密码,至少使用具有合理迭代量的PBKDF2。因此,您将让您的客户端执行HMAC(数据,PBKDF2(someSecret,1000)),服务器将只存储PBKDF2(someSecret,1000),然后执行HMAC(data,storedResult)。

答案 1 :(得分:1)

简短回答:实际上,没有。

答案很长:在任何一端散列密码都无济于事,因为攻击者现在可以使用密码的哈希进行身份验证。有关详细信息,请参阅维基百科有关质询 - 响应身份验证的文章中的this section

算法允许您验证用户的密码,而无需将其提供给您或您存储它,称为Zero Knowledge Password Proof。一个例子是Secure Remote Password Protocol。然而,这样的协议往往很复杂,而且自己实现这个协议很复杂,可能也是不明智的。

更简单的解决方案是使用公钥加密技术,并向用户发放您知道公共部分的私钥。然后,他们可以签署他们的消息进行身份验证并识别自己。 SSL / TLS提供了现成的实现。