不要再使用MD5和SHA1加密密码了

首先给大家推荐一下我老师大神的人工智能教学网站。教学不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵黄段子!点这里可以跳转到网站

为什么不要用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 )

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

补充一点,排序里面的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 攻击。
  • 但是除此之外,对密码的其他限制诸如密码中只允许使用某些字符,或者密码中不允许包含某些字符,就没有任何意义了。
  • 这样做不仅不会提高安全性,反而 降低了 安全性,而且真的没有任何理由需要这样做。 只要你对密码进行哈希处理了,那么无论是技术上,还是在存储上都没有任何限制。

点这里可以跳转到人工智能网站

发表评论