使用Perl的
crypt()
函数和随机盐对它们进行加密?这将限制密码的有效长度为8个字符,并且需要获取存储的密码以便与用户提供的密码进行比较(以获取附加的盐)。PostgreSQL中是否有内置的方法来完成此操作?
我应该使用Digest::MD5吗?
crypt()
函数和随机盐对它们进行加密?这将限制密码的有效长度为8个字符,并且需要获取存储的密码以便与用户提供的密码进行比较(以获取附加的盐)。不要使用SHA1或SHA256,尽管大多数人建议使用它们。 绝对不要使用MD5。
SHA1/256和MD5都是设计用来创建文件和字符串(以及必要时的其他数据类型)的校验和。由于这个原因,它们被设计成尽可能快,以便快速生成校验和。
这种快速性使得暴力破解密码变得更容易,因为一个写得好的程序可以轻松地每秒生成数千个哈希值。
相反,应该使用一种专门为密码设计的缓慢算法。它们被设计成要花费更长的时间来生成,好处是暴力攻击变得更加困难。因此,密码将更加安全。
如果你只是单独加密密码,即存储和检查密码的常规实现方式,你不会遇到任何显著的性能劣势。真正的差别只有在批量处理时才会体现。
我个人喜欢bcrypt。应该有Perl版本可供使用,通过快速的谷歌搜索可以找到几个可能的匹配项。
MD5通常被使用,但SHA1/SHA256更好。它们仍然不是最佳选择,但比MD5更安全。
所有通用哈希算法的问题在于它们被优化为快速处理。但是,当您将密码哈希值存储时,快速处理并不是您想要的——如果您可以在微秒内哈希密码,则表示攻击者能够尝试每秒一百万个密码,如果他们获得了您的密码数据库。
但您肯定想尽可能地减缓攻击者的速度,对吧?那么使用需要花费十分之一秒来哈希密码的算法是否更好呢?十分之一秒的速度足够快,以至于用户通常不会注意到,但是拥有您数据库副本的攻击者每秒只能尝试10个密码,寻找可用的登录凭据将需要比使用微秒每次尝试还多100,000倍的时间。使用微秒每次尝试的每小时成本变为使用十分之一秒每次尝试的11年。
那么,如何实现这一点呢?有些人通过运行多轮MD5/SHA摘要来模拟,但bcrypt算法是专门设计来解决此问题的。我并不完全理解其背后的数学原理,但我被告知它基于Blowfish帧的创建,这本质上是缓慢的(不像MD5操作可以在正确配置的硬件上大幅简化),并且它具有可调整的“成本”参数,因此,随着摩尔定律的推进,您只需要调整该“成本”来保持密码哈希值在十年后与今天一样慢。
在用户再次尝试之前设置延迟以及自动锁定(并带有自动管理员通知)也是一个好主意。
crypt
。虽然它很安全,但添加起来并不容易。如果您有一个好的代码级哈希算法,那可能是一个不错的替代方案。 - Kzqai使用加盐的SHA1或SHA256哈希方式。这是存储密码的最佳方法。
如果您不使用密码恢复机制(而非密码重置),我认为使用哈希机制比尝试加密密码更好。您可以在没有任何安全风险的情况下检查哈希值。即使您不知道用户的密码。
INSERT INTO user (password) VALUES (md5('some_salt'||'the_password'));
如果你想的话,你可以在perl中计算md5哈希值,除非你正在微调,否则没有太大区别。
你也可以使用sha1作为替代方案,但我不确定Postgres是否有本地实现。
我通常不鼓励使用动态随机盐,因为这是必须存储在数据库中的另一个字段。而且,如果您的表被攻击,盐将变得无用。
我总是使用一次性随机生成的盐,并将其存储在应用程序源或配置文件中。
使用md5或sha1哈希来存储密码的另一个好处是,您可以将密码列定义为固定宽度的CHAR(32)或CHAR(40)。