PHP 加密

来源:互联网 发布:战舰世界世界大和知乎 编辑:程序博客网 时间:2024/05/16 15:53

今天看了PHP加密的官方API,比如看到有crypt(),password_hash(),hash_equals()这些函数(md5,sha1等等hash加密就不讲了,hash部分查看官方API)。看到了“盐”salt的概念和“时序攻击的概念”。下面讲讲“盐”的作用和时序攻击。

首先要知道hash的不可逆的,结果唯一的。就是说通过“猜”的方式,如果猜的密码与用户的密码是一样的话,其hash值是一样的。以计算机的计算速度,暴利破解是可能的。我们可以通过让每一个hash随机化,同一个密码hash两次,得到的不同的hash来避免这种攻击。

具体的操作就是给密码加一个随即的前缀或者后缀,然后再进行hash。这个随即的后缀或者前缀成为“盐”。正如上面给出的例子一样,通过加盐,相同的密码每次hash都是完全不一样的字符串了。检查用户输入的密码是否正确的时候,我们也还需要这个盐,所以盐一般都是跟hash一起保存在数据库里,或者作为hash字符串的一部分。也就是说我们每个人的“盐”值是不一样的。

时序攻击

时序攻击属于侧信道攻击/旁路攻击(Side Channel Attack),侧信道攻击是指利用信道外的信息,比如加解密的速度/加解密时芯片引脚的电压/密文传输的流量和途径等进行攻击
的方式,一个词形容就是“旁敲侧击”。
举一个最简单的计时攻击的例子,某个函数负责比较用户输入的密码和存放在系统内密码是否相同,如果该函数是从第一位开始比较,发现不同就立即返回,那么通过计算返回的
速度就知道了大概是哪一位开始不同的,这样就实现了电影中经常出现的按位破解密码的场景。密码破解复杂度成千上万倍甚至百万千万倍的下降。
最简单的防御方法是:“发现错误的时候并不立即返回,而是设一个标志位,直到完全比较完两个字符串再返回”。

PHP加密中hash_equals()函数就是处于可能受到时序攻击的危险而存在的。根据官方API介绍:

hash_equals()比较两个字符串,无论它们是否相等,本函数的时间消耗是恒定的。本函数可以用在需要防止时序攻击的字符串比较场

景中, 例如,可以用在比较 crypt() 密码哈希值的场景。

crypt()


详情

password_hash()

例子:echo password_hash('rasmuslerdorf', PASSWORD_DEFAULT);
该例子每次运行的时候hash结果都是不一样的。因为其“盐”值并不是一成不变的,它会一直整容改变其“盐”值。同时其hash的算法和“盐”值都包含在hash的结果之中。PHP还提供password_verify()函数来判断明文密码与hash结果是否匹配,该函数同样是可以预防时序攻击(against timing attacks)。例如:
<?php// 想知道以下字符从哪里来,可参见 password_hash() 的例子$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';if (password_verify('rasmuslerdorf', $hash)) {    echo 'Password is valid!';} else {    echo 'Invalid password.';}?>
结果为:Password is valid!


0 0
原创粉丝点击