云服务器

经过各种安全事件后,很多系统在存放密码的时候不会直接存放明文密码了,大都改成了存放了 md5 加密(hash)后的密码,可是这样真的安全吗?

这儿找了个脚本来测试下MD5的速度

<?php

$testRounds = 100;

$testTimes  = 1000000;

$times = [];

$data = 'abcdefgh';

for ($i = 0; $i < $testRounds; $i++){

    $begin = microtime(true);

    for ($j = 0; $j < $testTimes; $j++){

        $hash = md5($data);

    }

    $times[] = microtime(true) - $begin;

}

print_r([

    'rounds' => $testRounds,

    'times of a round' => $testTimes,

    'avg' => array_sum($times) / count($times),

    'max' => max($times),

    'min' => min($times),

]);


测试结果:

[root@f4d5945f1d7c tools]# php speed-of-md5.php

Array

(

    [rounds] => 100

    [times of a round] => 1000000

    [avg] => 0.23415904045105

    [max] => 0.28906106948853

    [min] => 0.21188998222351

)


有没有发现一个问题:MD5速度太快了,导致很容易进行暴力破解.


简单计算一下:

> Math.pow(10, 6) / 1000000 * 0.234

0.234

> Math.pow(36, 6) / 1000000 * 0.234 / 60

8.489451110400001

> Math.pow(62, 6) / 1000000 * 0.234 / 60 / 60

3.69201531296

使用6位纯数字密码,破解只要0.234秒!

使用6位数字+小写字母密码,破解只要8.49分钟!

使用6位数字+大小写混合字母密码,破解只要3.69个小时!

当然,使用长一点的密码会显著提高破解难度:

> Math.pow(10, 8) / 1000000 * 0.234

23.400000000000002

> Math.pow(36, 8) / 1000000 * 0.234 / 60 / 60 / 24

7.640505999359999

> Math.pow(62, 8) / 1000000 * 0.234 / 60 / 60 / 24 / 365

1.6201035231755982

1.使用8位纯数字密码,破解要23.4秒!

2.使用8位数字+小写字母密码,破解要7.64小时!

3.使用8位数字+大小写混合字母密码,破解要1.62年!

但是,别忘了,这个速度只是用PHP这个解释型语言在个人电脑(i5-4460 CPU 3.20GHz)上跑出来的,还只是利用了一个线程一个CPU核心。若是放到服务器上跑,充分利用其多个线程,并使用C语言来重写下测试代码,那会是什么概念呢?更何况现在还有在线解密呢。更夸张的是,很多人的密码都是采用比较有规律的字母或数字,更能降低暴力破解的难度... 如果没有加盐或加固定的盐,那么彩虹表破解就表示同样没有太大压力啊(虽然选择使用简单的md5加密一下就存放的已经很少,但是我们很多时候是不知道别人是怎么加密的,会不会一步小心就暴露了)

强烈建议我们在设置密码时候还是尽量的位数多一些,复杂且随机哦。特别是不要在不同的情况下使用相同的密码,防止其中一环密码暴露了,那就整个信息都遭到暴露。例如我自己在设置密码时候,虽然我没有严格的执行不同情况下使用不同的密码,但是我会把密码进行分等级,例如我不重要的,可有可无的那种,我就来一个简单的数字字母组合;一般的我就设置一下自己容易记得的,稍微位数多一点;再往上的我就直接使用随机生成十五六位,最高级的我直接就记不得,例如支付之类的,用的时候再选择忘记密码去更改。或者某些硬件上的加密,就让别人知道密码也无法验证的那种。

提交成功!非常感谢您的反馈,我们会继续努力做到更好!

这条文档是否有帮助解决问题?

非常抱歉未能帮助到您。为了给您提供更好的服务,我们很需要您进一步的反馈信息:

在文档使用中是否遇到以下问题: