2010-01-07 108 views
17

在用Perl编写并使用PostgreSQL的Web应用程序中,用户拥有用户名和密码。建议存储密码的方式是什么?建议如何在数据库中加密用户密码?

使用Perl和随机盐的crypt()函数对它们进行加密?这将限制passswords的有用长度为8个字符,并且需要获取存储的密码以便与用户在认证(提取附加到其中的盐)时给出的密码进行比较。

在PostgreSQL中是否有内置的方式来执行此操作?

我应该用Digest::MD5

回答

-1

使用SHA1或SHA256哈希与腌制。这是存储密码的方式。

+1

还记得盐你的密码。 http://www.aspheute.com/english/20040105.asp – 2010-01-07 13:55:04

+0

请确保您不需要支持基于哈希的身份验证方案。由于支持LDAP {SSHA}方案的新要求,我很遗憾我决定在数据库中散列密码。 – 2010-01-07 14:30:36

+2

@ZZ编码器:为什么会出现这个问题?只需创建新的设置,并在用户登录时执行一些幕后的魔法,以便在新数据库中升级她。您应该*永远不会*存储可以以纯文本格式检索的密码,而散列则是一种很好的方法。 – 2010-01-07 19:02:14

-3

我建议将它存储为一个盐腌的md5散列。

INSERT INTO user (password) VALUES (md5('some_salt'||'the_password')); 

如果你愿意,你可以在perl中计算md5散列,除非你是微优化的,否则它没有太大的区别。

您也可以使用sha1作为替代,但我不确定Postgres是否具有本地实现。

我通常不鼓励使用动态随机盐,因为它是另一个必须存储在数据库中的字段。另外,如果你的桌子受到损害,盐变得毫无用处。

我总是随机生成一次性盐,并将其存储在应用程序源代码或配置文件中。

对密码使用md5或sha1散列的另一个好处是您可以分别将密码列定义为md5和sha1的固定宽度CHAR(32)或CHAR(40)。

+2

一段时间以来,MD5被认为是不安全的。应该使用SHA1或SHA256 – EKS 2010-01-07 09:29:26

+4

呃,我也读过这些博客文章。对于90%(任意)的用例来说,md5已经足够了。 – hobodave 2010-01-07 09:38:28

+0

是的,但是如果sha1的工作方式相同,为什么要使用md5,并提供更多的安全性?在sha1上方选择md5没有意义,除非您的存储空间或计算能力有限。 – Henri 2010-01-07 09:42:18

0

如果您不使用密码恢复机制(不是密码重置),我认为使用哈希机制比尝试加密密码要好。你可以检查哈希值,没有任何安全风险。即使你不知道用户的密码。

+1

考虑到他提到了Perl的crypt()函数,它“恰如C库中的crypt(3)函数一样创建摘要字符串”,我怀疑他/她知道他们应该使用哈希机制,并且使用了错误的术语。 – 2010-01-07 09:49:54

2

PostgreSQL中的pgcrypto模块已经内置了密码散列suppotr,这是非常聪明的存储,生成,多算法等见http://www.postgresql.org/docs/current/static/pgcrypto.html,在密码散列函数部分。您还可以看到http://www.hagander.net/talks/hidden%20gems%20of%20postgresql.pdf的pgcrypto部分。

+0

我最近已经实现了pgcrypto,并且在你的数据库上工作很烦人(而且你必须真正小心你的查询使用它,如果你以某种方式格式化它们,真的会减慢执行速度)。你必须安装模块,以root身份运行一个脚本,然后才能使用'crypt'。它是安全的,但不容易添加。 如果你有一个好的代码级哈希算法,那可能是一个好的选择。 – Kzqai 2010-06-29 23:00:29

17

MD5常用,但SHA1/SHA256更好。仍然不是最好的,但更好。

所有这些通用哈希算法的问题是,它们的优化速度很快。然而,当你将你的密码散列存储时,快速就是你想要的不需要 - 如果你可以在一微秒内散列密码,那么这意味着攻击者每秒可以尝试一百万个密码手上你的密码数据库。

但是你想尽可能减慢攻击者的速度,不是吗?使用一个十分之一秒的算法来代替密码是不是更好?十分之一秒仍然足够快以至于用户通常不会注意到,但拥有数据库副本的攻击者每秒只能尝试10次尝试 - 要花10万次才能找到工作集的登录凭证。每个小时,每次尝试只需要十分之一秒的时间,每次尝试的时间就会变成11个

那么,你如何做到这一点?一些人通过运行多轮MD5/SHA消解来伪造它,但是bcrypt算法是专门为解决这个问题而设计的。我不完全理解它背后的数学,但我被告知它基于Blowfish框架的创建,这本质上很慢(不像MD5操作,它可以在正确配置的硬件上大大精简),它有一个可调的“成本”参数,因此,随着摩尔定律的发展,您所需要做的就是调整“成本”,以便在今天的十年内保持密码散列速度与十年一样缓慢。

+0

+1。有趣。 – 2010-01-08 00:16:41

+0

+1注意到更安全的方法的额外时间通常不会被最终用户注意到。 – 2011-04-05 16:32:37

29

不像大多数人所暗示的那样,不要使用SHA1或SHA256绝对不要使用MD5

SHA1/256和MD5都设计用于创建文件和字符串(以及其他数据类型,如有必要)的校验和。正因为如此,它们被设计得尽可能快,所以校验和很快产生。

这样快的速度使密码暴力变得更容易,因为一个写得很好的程序很容易每秒产生数以千计的哈希值。

而是使用专门为密码设计的缓慢算法。它们的设计需要花费更长时间才能生成,其优势在于暴力攻击变得更加困难。正因为如此,密码将更安全。

如果您只是一次只查看一个密码,这是存储和检查密码的常规实现,您不会遇到任何重大的性能劣势。它只是在实际区别的大部分。

我个人比较喜欢bcrypt。应该有一个可用的Perl版本,因为快速的谷歌搜索产生了几个可能的匹配。

+1

你不知道你在说什么,远离安全标签。消息摘要算法意味着要快速消解数据,并尽量不可逆转。 NIST不会批准缓慢的加密算法。 – rook 2010-01-08 02:55:34

+0

我不是在说反转,我在说暴力。如果我不知道我在说什么,我认为像Paul Buchheit(1)(Gmail的创建者)和Phusion(2)这样的人也不知道?即使Google建议(3)在其中一个项目中进行加密。这些只是我通过谷歌搜索“使用bcrypt”发现的一些链接。 – vonconrad 2010-01-08 03:41:55

+0

以前评论的链接: 1:http://paulbuchheit.blogspot.com/2007/09/quick-read-this-if-you-ever-store.html 2:http://blog.phusion .nl/2009/08/13/secure-store-passwords-with-bcrypt-ruby-now-compatible-with-jruby-and-ruby-1-9/ 3:http://code.google。com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ – vonconrad 2010-01-08 03:46:14

3

我喜欢bcrypt最好的,SHA2(256)接近第二。我从来没有见过MD5用于密码,但也许有些应用程序/库使用它。请记住,你应该总是使用盐。盐本身应该是完全独特的每个用户,并在我看来,尽可能长。我永远不会只用一个哈希来对付一个没有添加盐的字符串。主要是因为我有点偏执,还有一点更加面向未来。

在用户再次尝试和自动锁定(使用自动管理通知)之前延迟也是一个好主意。

相关问题