单向散列函数
1. 单向散列函数
单向散列函数 ------- 获取消息的指纹
在刑事侦查中,侦查员会用到指纹。通过将犯罪现场采集的指纹与指纹库比对,或与嫌疑人的指纹进行比对,就能够知道谁与案件有关联
在计算机中,有时候也会用到"指纹"。当需要比较两条消息是否一致时,通常不必对消息内容比较,直接比较它们的"指纹"就行。
1.1 什么是单向散列函数
单向散列函数,有一个输入和一个输出,其中输入称为消息(message),输出称为散列值(hash value)。单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检查消息的完整性。 简单说就是把任意长度的内容转换成固定长度的输出串,且通过输出串难以还原 原始内容
这里的消息不一定是人能看懂的文字,可以是图片或者声音文件。单向散列函数不需要知道消息实际代表的含义。无论任何消息,单向散列函数都会将它作为单纯的比特序列来处理。即根据比特序列计算出散列值
散列值的长度和消息的长度无关。无论消息多大,单向散列函数都会计算出固定长度的散列值。以sha-1单向散列函数为例,它计算出的散列值的长度永远都是160比特(20字节)。
1.2 术语
单向散列函数相关的术语,有很多变体,不同参考资料中所使用的术语也不同。
单向散列函数也被称为消息摘要函数(message digest function) 、哈希函数或者杂凑函数
输入单向散列函数的消息也成为原像(pre-image)。
单向散列函数的输出值也称为消息摘要(message digest)护或者指纹(fingerprint)。
完整性也成为一致性。
1.3 单向散列函数的特性
通过使用单向散列函数,即便是确认几百MB大小的文件完整性,也只要对比很小的散列值就可以了。通常将单向散列函数拥有以下特性。
- 根据任意长度的消息计算出固定长度的散列值
首先,单向散列值的输入必须能够是任意长度的消息。
无论输入多长的消息,单向散列函数必须能够生成很短的散列值。
- 能够快速计算出散列值
计算散列值所花费的时间必须要短。
- 消息不同散列值也不同
为了能够确认完整性,消息中哪怕只有1比特的改变,也必须有很高概率产生不同的散列值。
两个不同的消息产生同一个散列值的情况被称为碰撞(collsion)。
难以发生碰撞的性质称为抗碰撞性。密码技术中所使用的单向散列函数,都要具备抗碰撞性。
- 具备单向性
单向散列函数必须具备单向性(one-way)。 单向性指的是无法通过散列值反算出消息的性质。根据消息计算出散列值可以很容易,但计算路径无法反推。
正如同将玻璃粉碎很容易,却无法将碎片还原成原先的玻璃。估计消息计算出散列值很容易,但根据散列值却无法逆推算出消息。
单向散列函数并不是一种加密,因此无法通过解密将散列值还原为原阿里的消息。
1.4 单向散列函数的实际应用
1.4.1 检测软件是否被篡改
可以使用单向散列函数来确认自己下载的软件是否被篡改。
很多软件,都会把散列值公布在官方网站上。用户下载完软件后可自行计算散列值,与官方的散列值进行比对。来确认自己下载的软件是否与提供者的一致。
为了减轻服务器压力,很多软件都会借助多个网站(镜像站点)发布软件,在这种情况下,单向散列函数就会在检测软件是否被篡改方法发挥重要作用。
1.4.2 消息认证码
使用单向散列函数可以构造消息认证码
消息认证码是将"发送者和接收者之间的共享密钥"和"消息",进行混合计算后得到的散列值。使用消息认证码可以检测并防止通信过程中的错误,篡改以及伪装。
消息认证码在SSL/TLS中也有使用
1.4.3 数字签名
在进行数字签名时会使用单向散列函数。
数字签名是现实社会中的签名(sign)和盖章这样的行为在电脑世界的实现。数字签名的过程非常耗时,因此一般不会对整个消息内容直接施加数字签名,而是先通过单向散列函数计算出消息的散列值,然后在对这个散列值施加数字签名。
1.4.4 伪随机生成器
使用单向散列函数可以构造伪随机数生成器。
密码技术中所使用的随机数需要具备"事实上不可能根据过去的随机数列预测未来的随机数列"这样的性质。为了保证不可预测性,可以利用单向散列函数的单向性。
1.4.5 一次性口令
使用单向散列函数可以构造一次性口令(one-time password)
一次性口令经常被用于服务器对客户端的合法性认证。在这种方式中,通过使用单向散列函数可以保证口令在通信链路上传送一次(one-time),因此即使窃听者窃取了口令,也无法使用。
1.5 常用的单向散列函数
MD4 MD5 SHA1 SHA-224 SHA-256 SHA-384 SHA-512
算法 | 比特数 | 字节数 |
---|---|---|
MD4 | 128bit | 16byte |
MD5 | 128bit | 16byte |
SHA-1 | 160bit | 20byte |
SHA-224 | 224bit | 28byte |
SHA-256 | 256bit | 32byte |
SHA-384 | 384bit | 48byte |
SHA-512 | 512bit | 64byte |