您的位置 首页 php

php加密技术原理浅析(一):单向散列加密

单向散列加密

散列是信息的提炼,通常其长度要比信息小得多,且为一个固定长度。加密性强的散列一定是不可逆的,这就意味着通过散列结果,无法推出任何部分的原始信息。任何输入信息的变化,哪怕仅一位,都将导致散列结果的明显变化,这称之为雪崩效应。散列还应该是防冲突的,即找不出具有相同散列结果的两条信息。具有这些特性的散列结果就可以用于验证信息是否被修改。单向散列函数一般用于产生消息摘要,密钥加密等,常见的有: MD5, SHA。

MD5

简介 : Message Digest Algorithm MD5(即消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。

特点 :

  • 压缩性: 任意长度的数据,算出的 MD5 值长度都是固定的。

  • 容易计算 : 从原数据计算出 MD5 值很容易。

  • 抗修改性 : 对原数据进行任何改动,哪怕只修改1个字节,所得到的 MD5 值都有很大区别。

  • 强抗碰撞 : 已知原数据和其 MD5 值,想找到一个具有相同 MD5 值的数据(即伪造数据)是非常困难的。

  • 应用 : 一致性验证,数字签名,安全访问认证。

  • 弱点 : 目前已经可以暴力破解 MD5 的值了,即逆推回去。并且从理论上来说 MD5 并不是绝对的唯一,所以在某些极限条件下还是会出现重复的情况的。

SHA-1

SHA (Secure Hash Algorithm ,安全散列算法),SHA-1 属于 SHA 中最常见的一种另外其他还有 SHA-256,SHA-384 和 SHA-512。

特点和应用领域都和 MD5 类似,区别在于 SHA-1 更加安全,但是会慢一些。但是目前 Google 已经宣布可以破解了。。。并且即使是 SHA-256,SHA-384 和 SHA-512 也不能完全保证绝对的安全。

单向散列加密的 php 代码示例

/**
* md5
**/echo 'md5: ' . PHP_EOL;
var_dump(md5('password string.')); // 32 byte
var_dump(md5('password string.', TRUE)); // 16 byte (默认是16byte的原始二进制格式,会显示乱码,解决方案如下)
var_dump(substr(md5('password string.'), 8, 16)); // 16byte乱码解决方案:32byte时的第8到24位之间的内容和16byte情况下的值是一样的,可以截取下就行
/**
*  sha1 
**/echo 'sha1: ' . PHP_EOL;
var_dump(sha1('password string.')); // 40byte
var_dump(sha1('password string.', TRUE)); // 20byte (默认是16byte的原始二进制格式,会显示乱码,解决方案如下)
var_dump(substr(md5('password string.'), 8, 16)); // 20byte乱码解决方案:40byte时的第10到30位之间的内容和20byte情况下的值是一样的,可以截取下就行
/**
* hash
**/echo 'hash: ' . PHP_EOL;
var_dump(hash('sha512', 'password string.')); // hash支持多种 哈希算法 ,这里演示‘sha512’方式。512bit,即128byte
var_dump(hash('sha512', 'password string.', TRUE)); // 还支持第三个参数用于输出截取后的原始二进制值,不同算法长度不同
/**
* crypt
**/echo 'crypt: ' . PHP_EOL;
var_dump(crypt('password string.')); // 默认创建出来的是 弱密码 ,即没有加盐则会有不同的算法自动提供,php5.6及之后的版本会报个提示
var_dump(crypt('password string.', '$1$rasmusle$')); // 加的盐值也应该设置一定的复杂度,并且由于不同系统使用的算法不一致所以可能会导致得到的结果也不一致,可以用默认的crypt来生成盐值
var_dump(hash_equals(crypt('password string.'), crypt('password string.', crypt('password string.'))));
// 这里用默认的crypt来生成盐值,这样就避免了不同算法的问题
// hash_equals比较两个 字符串 ,无论它们是否相等,本函数的时间消耗是恒定的。这里就可以专门用来crypt函数的时序攻击
// 这里再科普一下时序攻击:一句话就是通常比较密码时计算机从头开始按位逐次比较遇见不同就返回false,因为计算速度是一定的,
// 那么等于说可以根据这个计算时间来推断大概多少位的时候开始不一样了,这样就大大降低了破译密码的难度了
/**
* password_hash
**/echo 'password_hash: ' . PHP_EOL;
var_dump(password_hash('password string.', PASSWORD_DEFAULT));
// password_hash是crypt的一个简单封装,并且完全与现有的密码哈希兼容,所以推荐使用
// 第二个参数指明用什么算法,目前支持:PASSWORD_DEFAULT和PASSWORD_BCRYPT,通常使用前者,目前是60个字符,但是以后可能会增加,所以数据库可以设置成255个字符比较稳妥,后者生成长度为60的兼容使用 "$2y$" 的crypt的字符串
// 第三个参数是加盐,php7之后已经废除了,因为默认会给出一个高强度的盐值
var_dump(password_verify('password string.', password_hash('password string.', PASSWORD_DEFAULT))); // password_verify是专门用来比较用password_hash生成的密码的,可以防止时序攻击,可以参考hash_equals之于crypt 

文章来源:智云一二三科技

文章标题:php加密技术原理浅析(一):单向散列加密

文章地址:https://www.zhihuclub.com/152716.shtml

关于作者: 智云科技

热门文章

网站地图