我正在寻找一种用salt存储和验证mysql密码的方法。我没有访问PHP或任何其他加密软件的权限。我知道PASSWORD()函数,但它不允许使用salt。
还有其他选择吗?
我认为,既然你谈论的是盐,那么你真正指的是哈希,这是单向密码学的一种形式,而不是加密。散列保证给定的输入值总是产生相同的输出值。使用安全的哈希算法,除了尝试哈希函数中的每个明文值之外,没有更好的方法来导出原始明文。
虽然SHA1可能足以保护许多系统的密码,但肯定有更好的哈希算法。然而,SHA1在MySQL中是可用的。
虽然SHA1()
MySQL函数不接受单独的salt参数,但您仍然可以对密码进行salt处理。事实上,我所知道的大多数散列函数都没有单独的salt参数。
要对明文值加盐,只需将一个随机字符串连接到明文值的开头。不幸的是,MySQL没有一个简单的方法来生成随机字符串,但这会让你很接近。
生成6个字符(仅十六进制值)的随机字符串:
SELECT SUBSTRING(SHA1(RAND()), 1, 6) AS salt
当然,重要的是你必须时刻节约盐。你会再次需要它的。
一旦你保存了salt,只需像这样散列密码:
SELECT SHA1(CONCAT(salt, 'password')) AS hash_value
通常将salt和散列后的密码存储在同一列中,方法是在散列值前面加上salt。
要验证输入的密码,只需重复此过程。用存储的salt作为明文密码的前缀,对连接的字符串进行散列,然后将生成的散列值与存储的密码散列进行比较。
每个记录应该有不同的随机盐。
遗憾的是,仅使用SQL命令无法安全存储密码。
由于应该在哈希方案中添加随机salt,因此如果用户尝试登录,则无法验证密码。您必须读取用户表中每一行的salt,并计算哈希进行比较。
一个安全的哈希函数可以调整为需要一定的时间(例如10ms),例如BCrypt就有成本因素。如果必须检查每一行,并且每次计算都需要一些时间,那么如果用户表增长,就会遇到问题。
这些就是为什么密码不应该由数据库本身散列的原因。首先,您必须根据给定的用户名找到哈希及其salt,然后您可以验证这一行的密码。
这里有两个很棒的链接:
http://www.aspheute.com/english/20040105.asp
http://alias.io/2010/01/store-passwords-safely-with-php-and-mysql/
首先,你不想"加密"你的密码。加密意味着它们可以被解密。。。这不是一件好事。您希望对它们进行散列处理,使它们成为单程票(例如SHA512())。
注意:MD5不应用于安全的密码哈希。它很容易破裂。
这里是salt的简化/解释:salt向密码散列添加随机值。Salt对于每个密码都是唯一的。(每个密码的salt都需要与密码一起存储)。每个密码都有唯一的salt,字典攻击(密码破解技术)基本上没有机会。
所以,只需在你的密码中添加一些盐,比如:
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
并将其与密码一起存储,或者作为cookie存储,或者两者兼而有之。
希望能有所帮助。