为什么在建用户表的时候一般都会加个salt字段,然后计算password的时候,会根据注册页面输入的密码和随机生成的salt值一起做MD5加密,这样做有什么好处啊,大神们给个详细的解释。
为什么在建用户表的时候一般都会加个salt字段,然后计算password的时候,会根据注册页面输入的密码和随机生成的salt值一起做MD5加密,这样做有什么好处啊,大神们给个详细的解释。
经过MD5加密的弱密码仍然可以通过穷举或彩虹表破解,加盐是为了增加MD5破解难度从而提高安全性。
主要是为了避免数据库被窃取后,直接获取用户的密码明文.
PHP密码散列安全
密码散列相关函数:
password_hash(推荐) crypt(blowfish) hash sha1 md5
hash函数支持多种哈希算法hash_algos,比如sha512.
PHP 5.5开始提供了一个原生密码散列API(password_hash/password_verify),
它提供一种安全的方式来完成密码散列和验证.
PHP 5.3.7及后续版本中提供了一个纯PHP的原生密码散列API的兼容库.
当PHP版本不支持password_hash/password_verify时,改用crypt实现.
如果使用crypt()函数来进行密码验证,那么你需要选择一种耗时恒定的字符串比较算法来避免时序攻击.
耗时恒定就是字符串比较所消耗的时间恒定,不随输入数据的多少变化而变化.
PHP中的==
和===
操作符和strcmp()
函数都不是耗时恒定的字符串比较,
但是password_verify()
可以帮你完成这项工作.
所以我们鼓励你尽可能的使用原生密码散列API.
加解密领域中的"盐"是指在进行散列处理的过程中加入的一些数据,
用来避免从已计算的散列值表(被称作"彩虹表")中对比输出数据从而获取明文密码的风险.
简单而言,"盐"就是为了提高散列值被破解的难度而加入的少量数据.
现在有很多在线服务都能够提供计算后的散列值以及其对应的原始输入的清单,并且数据量极其庞大.
通过加"盐"就可以避免直接从清单中查找到对应明文的风险.
彩虹表是一个用于加密散列函数逆运算的预先计算好的表,常用于破解加密过的密码散列.
password_hash()函数会随机生成"盐".
当使用password_hash()或者crypt()函数时,"盐"会被作为生成的散列值的一部分返回.
你可以直接把完整的返回值存储到数据库中,因为这个返回值中已经包含了足够的信息.
可以直接用在password_verify()或crypt()函数来进行密码验证.
盐还有个用处就是可以用来做识别用户身份的cookie,
比如基于数据库实现一套自定义的cookie会话机制:
这个cookie既要做到认证用户,又要做到不能被伪造和破解.
<code>//保护用户密码的盐 $salt = sha1( uniqid(getmypid().'_'.mt_rand().'_', true) ); //数据库保存的用户密码($pwd_user是用户输入的密码明文) $pwd_db = sha1($salt.sha1($pwd_user)); //cookie里的盐 //其中$global_salt是配置里定义的全局盐,用来保护用户的盐,一旦修改,所有用户的cookie都将失效. $cookie_salt = sha1($global_salt.sha1($salt)); //最终生成的cookie内容 $cookie = base64_encode($user_id.'|'.$cookie_salt); //如果你需要高安全性,还可以使用MCRYPT_BLOWFISH对整个cookie的内容做一次加密. $cookie = mcrypt_blowfish($cookie, $key); //设置cookie,这里把过期时间设为604800秒(60*60*24*7,一周) setcookie('sessid', $cookie, time()+604800, '/', '', false, true); //解密cookie $cookie = mdecrypt_blowfish($_COOKIE['sessid'], $key); //解码分割后拿到里面的$user_id和$cookie_salt $cookie = explode('|', base64_decode($_COOKIE['sessid'])); list($user_id, $cookie_salt) = $cookie;</code>
用 bcrypt 吧,PHP 5.5.0 默认算法了都。
咋还 md5 呢?
http://zhuanlan.zhihu.com/p/2...