不要再使用MD5和SHA1加密密码了!
2017-05-11 15:09
429 查看
为什么不要用MD5和SHA1,下面会详细讲到!
<?php define('testtime', 50000); $algos = hash_algos(); //返回一个数值索引的数组, 包含了受支持的哈希算法名称。 //遍历算法,每个算法计算50000次的时间 foreach ($algos as $algo) { $st = microtime(true); for ($i = 0; $i < testtime; $i++) { hash($algo, microtime(true) . $i); } $et = microtime(true); $time[$algo] = $et - $st; } asort($time, SORT_NUMERIC); echo ""; print_r($time); //CI框架建不用MD_5和SHA1加密密码,php本身由一个专门来加密密码的函数: echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT) . "\n"; //输出结果类似: $2y$10$duGmwKVqHf7sgulBOd1gb.cIikNHx3dtmlsRg9yx/YvOelJSkPmpC //PASSWORD_DEFAULT - 使用 bcrypt 算法 (PHP 5.5.0 默认)。 注意,该常量会随着 PHP 加入更新更高强度的算法而改变。 所以,使用此常量生成结果的长度将在未来有变化。 因此,数据库里储存结果的列可超过60个字符(最好是255个字符)。
输出结果如下:
Array ( [crc32b] => 0.031200170516968 [sha1] => 0.045201063156128 [adler32] => 0.046799898147583 [crc32] => 0.046799898147583 [fnv1a64] => 0.046800136566162 [fnv1a32] => 0.046801090240479 [md5] => 0.055202007293701 [md4] => 0.062399864196777 [fnv164] => 0.062399864196777 [fnv132] => 0.062399864196777 [joaat] => 0.062399864196777 [ripemd160] => 0.062399864196777 [sha256] => 0.062399864196777 [ripemd256] => 0.062400102615356 [tiger128,3] => 0.062400102615356 [tiger128,4] => 0.062400102615356 [tiger160,4] => 0.062400817871094 [tiger192,4] => 0.064400196075439 [tiger192,3] => 0.065399885177612 [tiger160,3] => 0.066400051116943 [ripemd128] => 0.068401098251343 [haval192,3] => 0.073400974273682 [sha224] => 0.078000068664551 [ripemd320] => 0.079999923706055 [haval256,3] => 0.085000991821289 [haval160,3] => 0.089000940322876 [haval128,4] => 0.089999914169312 [haval224,4] => 0.093599796295166 [haval192,5] => 0.093600034713745 [haval192,4] => 0.093600034713745 [haval256,4] => 0.094600200653076 [haval256,5] => 0.094600200653076 [haval160,4] => 0.095601081848145 [haval128,3] => 0.096001148223877 [haval224,3] => 0.1030011177063 [haval128,5] => 0.10920000076294 [whirlpool] => 0.10920095443726 [haval160,5] => 0.11120080947876 [haval224,5] => 0.12479996681213 [sha384] => 0.14040017127991 [sha512] => 0.14339995384216 [gost-crypto] => 0.14740014076233 [gost] => 0.15600109100342 [snefru256] => 0.25960087776184 [snefru] => 0.26519989967346 [md2] => 0.36480093002319 )
补充一点,排序里面的flag值:
SORT_REGULAR- 正常比较单元(不改变类型)SORT_NUMERIC - 单元被作为数字来比较
SORT_STRING - 单元被作为字符串来比较
SORT_LOCALE_STRING - 根据当前的区域(locale)设置来把单元当作字符串比较,可以用 setlocale() 来改变。
SORT_NATURAL - 和 natsort() 类似对每个单元以”自然的顺序”对字符串进行排序。 PHP 5.4.0 中新增的。
SORT_FLAG_CASE - 能够与 SORT_STRING 或 SORT_NATURAL 合并(OR 位运算),不区分大小写排序字符串。
验证密码:
password_verify— 验证密码是否和哈希匹配,时序攻击
(timing attacks)对此函数不起作用。 注意
password_hash()返回的哈希包含了算法、 cost 和盐值。 因此,所有需要的信息都包含内。使得验证函数不需要储存额外盐值等信息即可验证哈希。
boolean password_verify ( string $password , string $hash )
<?php // 想知道以下字符从哪里来,可参见 password_hash() 的例子 $hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq'; if (password_verify('rasmuslerdorf', $hash)) { echo '密码正确!'; } else { echo '密码错误!'; }
密码处理
在你的应用程序中正确处理密码是非常关键的。
但是不幸的是,许多开发者并不知道怎么去做,而且网络上充斥着大量过时的 甚至错误的建议,提供不了任何帮助。
我们提供了一个清单来帮助你,告诉你什么该做,什么不该做。
绝不要以明文存储密码。
永远使用 哈希算法 来处理密码。
绝不要使用 Base64 或其他编码方式来存储密码。
这和以明文存储密码是一样的,使用 哈希 ,而不要使用 编码 。
编码以及加密,都是双向的过程,而密码是保密的,应该只被它的所有者知道, 这个过程必须是单向的。哈希正是用于做这个的,从来没有解哈希这种说法, 但是编码就存在解码,加密就存在解密。
绝不要使用弱哈希或已被破解的哈希算法,像 MD5 或 SHA1 。
这些算法太老了,而且被证明存在缺陷,它们一开始就并不是为了保存密码而设计的。
另外,绝不要自己发明算法。
只使用强密码哈希算法,例如 BCrypt ,在 PHP 自己的 密码哈希 函数中也是使用它。
即使你的 PHP 版本不是 5.5+ ,也请使用它们,CodeIgniter 为你提供了这些算法。
如果你连升级 PHP 也无法做到,那么使用 hash_pbkdf() http://php.net/hash_pbkdf2 吧, 为实现兼容性我们提供了这个函数。
绝不要以明文形式显示或发送密码。
即使是对密码的所有者也应该这样。如果你需要 “忘记密码” 的功能,可以随机生成一个新的 一次性的(这点很重要)密码,然后把这个密码发送给用户。
绝不要对用户的密码做一些没必要的限制。
如果你使用除 BCrypt(它有最多 72 字符的限制)之外的其他哈希算法,你应该设置一个相对长一点的密码长度(例如 1024 字符),这样可以缓解 DoS 攻击。
但是除此之外,对密码的其他限制诸如密码中只允许使用某些字符,或者密码中不允许包含某些字符,就没有任何意义了。
这样做不仅不会提高安全性,反而 降低了 安全性,而且真的没有任何理由需要这样做。 只要你对密码进行哈希处理了,那么无论是技术上,还是在存储上都没有任何限制。
相关文章推荐
- JS实现密码加密(base64, md5, sha1)
- JS实现密码加密(base64, md5, sha1)
- javascript实现base64 md5 sha1 密码加密
- JS实现密码加密(base64, md5, sha1)
- javascript实现base64 md5 sha1 密码加密
- .net自动发送邮件,适用于MD5或sha1加密后的密码取
- 用Gpu破解md5、sha1等加密密码的软件
- MD5,sha1,sha,AES加密
- C#:使用MD5对用户密码加密与解密
- 密码加密之MD5+Base64
- iOS开发之算法加密md5,sha1,AES,base64
- 使用Apache digest可以做md5 SHA1 BASE64加密
- 密码学4——Java 加密解密之消息摘要算法(MD5 SHA MAC)
- java 密码加密--MD5以及异或加密
- android MD5和SHA1加密实例
- 微信小程序 sha1 实现密码加密
- [置顶] App安全登录之密码、通讯加密方法(MD5,Base64,RSA,AES)
- java加密用户登录密码--不用MD5实现
- java中使用MD5对密码进行加密