我正在 LAMP(erl) 堆栈上进行开发,并且知道几种存储模糊密码的方法。鉴于 MySQL 4.1.1 和 Perl 5.8,我想听听那些认为他们有最佳实践的人的意见,以及它是最佳实践的原因。
我读过的一个选项,使用 MySQL ENCODE() 和 DECODE() 函数,对我来说听起来不错……你的想法?
通常,我更喜欢将密码保存为无法恢复的哈希值,而不是可以解密的加密项目。
通过从访问者提供的字符串(当然还有一些盐)计算哈希值,我可以判断用户是否两次提供了相同的密码,而没有允许我的应用程序能够解密提供的密码的安全风险,可能是恶意的.
我的感觉是,当您希望数据可恢复时, encode() 和 decode() 可能是很好的解决方案,但不可恢复的哈希(使用 Crypt::MD5)是存储密码的更好方法。
我认为具有适当散列函数(如SHA-256 )的盐渍散列是最好的。可撤销的密码不如不可撤销的密码安全。如果没有外部 Perl 模块,您可以使用内置的 SHA1() 函数,不如 SHA256,但比 ENCODE/DECODE 更好。
此外,您必须考虑从代码到数据库的路径,该路径可以被嗅探。您可以通过在代码中散列或加密数据库连接来避免这种风险。最好在代码中执行此操作,因为即使在加密连接时,仍然存在配置查询日志的风险,因此将明文存储在某处的日志文件中。
如果您只需要密码来验证您自己/用户的身份,那么一种存储方式(如 md5)会更好。
好吧,既然有一个DECODE()
功能,我会说不,因为您可能希望以散列形式存储密码,以防止任何人获取您的数据库/密码文件随便读取密码。
我建议使用经典的盐渍哈希方法。
一些应用程序要求用户的密码是可检索的,这与用户密码被随机重置的系统相反,如果忘记了(因为它无法解密,因为您使用的是哈希)。在这种情况下,编码和解码都可以,但为什么不使用内置的 AES_ENCRYPT 和 AES_DECRYPT 函数呢?
此外,无论您是散列还是加密,都请遵循使用盐值的建议。在这两种情况下都是有益的。
我不确定这些函数的作用,但对于 LAMP 堆栈网站中的密码,我肯定也会使用盐域。
您的用户表将具有:
然后在纯文本密码和盐的串联上使用一些编码函数对纯文本密码进行编码。该结果进入通过字段。盐也被储存起来。这样你就可以在用户登录时验证明文密码。盐可以是任何东西,越长越随机越好,但我不认为它那么敏感。
这极大地提高了安全性,因为现在您的用户不再使用 5 个字母的密码,他们使用 5+len(salt) 大小的密码,如果盐足够大,彩虹数据库将永远不会包含您的哈希值。
如果您可以解密密码,则说明您的安全性存在缺陷。您应该始终使用盐对密码进行散列,MD5 很流行,但也有更好的散列,例如 SHA 和 SHA-256。