单向散列函数
以下大部分内容摘自《图解密码技术》
什么是单向散列函数
单向:只能单向进行,不可逆。所以不能用来做加解密
散列:得出散列值
函数:一种算法(SHA1,SHA256,SHA512)
目的
确认内容的完整性(integrity)
特点
- 输出的散列值总是固定长度(例如SHA1总是160bit,无论输入内容多大)
- 能够快速计算散列值
- 消息哪怕改动了一点,算出来的散列值变化就很大
- 单向性,不是加密,所以没办法解密。即根据散列值计算出原值
术语
- 单向哈希函数也称为哈希函数,message digest function,杂湊函数
- 单向哈希函数的输入消息也称为pre-image
- 单向哈希函数的输出也成为message digest,fingerprint
实际应用
- 检测文件是否被修改。例如各大网站的软件安装包,通常都有checksum
- Password-Based-Encryption,基于口令的加密
- 消息认证码MAC
- 数字签名
- 伪随机数生成器
- 一次性密码 OTP one time password
单项散列函数的具体例子
- MD4(128bit散列值),MD5(128bit散列值)。MD4和MD5已经不推荐使用
- SHA1,160bit散列值,2005年山东大学王小云教授攻破,不推荐使用
- SHA256,256bit,SHA384,384bit,SHA512,512bit。SHA256,SHA384,SHA512统称为SHA2
- RIPEMD-160,160bit
- AHS Advanced Hash Standard和SHA3
单项散列值无法解决的问题
能保证消息的完整性,但是无法进行认证。即只能辨识消息发送的内容的完整性,却不能辨别消息发送者是否是期望的发送者
要对消息发送者进行认证,需要用到消息认证码(MAC)和数字签名
消息认证码MAC
MAC的构成部分
- 任意长度的输入
- 发送者和接收者之间共享的密钥
- 根据算法计算,输出固定长度的数据(MAC值)
如何使用MAC
- 发送者和接收者实现共享密钥
- 发送者对消息原文(利用密钥)生成MAC值
- 发送消息原文和MAC
- 接收者接收原文和MAC值,利用同样的步骤(共享密钥),对原文计算MAC,与收到的MAC比对,如果相同,证明消息未篡改,并且确实由消息发送者发送。
密钥如何共享
密钥的配送,可采用公私钥,Diffie-Hellman密钥交换,密钥分配中心,或者其他方式
应用实例
- SWIFT
- IPsec
- TLS/SSL
实现方式
- 使用SHA1,MD5等单向散列函数,例如HMAC
- 使用DES,AES
- 使用流密码和公钥密码
对MAC的攻击
重放攻击
防御措施:
- 每次发送消息,增加一个序列号。由于每次序列号不一致,导致消息原文不一致,从而是MAC值每次不一样
- 时间戳。每次发送消息时包含当前时间戳。如果时间戳小于当前时间戳,表明是旧消息,认为该消息不可用。要求发送者/接收者时间保持一致,而且通信的验证,所以需要有一点的时间偏差(缓冲)
- nonce。每次消息发送前,接收者向发送者发送一个nonce。发送者在消息中包含nonce。
密钥推测攻击
MAC无法解决的问题
- 对第三方验证
Bob收到Alice的消息,无法向第三方Victor证明消息是由Alice发出的。因为Alice和Bod都拥有共享密钥,都可以发送消息
如何解决:数字签名 - 防止否认
Bob收到了Alice的消息,但是无法证明消息是Alice发送的。Alice可以否认消息不是她发送的,因为Bob也拥有密钥。
如何解决:数字签名
数字签名
消息到底是谁写的
什么是数字签名
消息发送者,有一个自己的密钥,其他人不知道,发送者利用该密钥,对发送的消息进行数字签名(生成一段只有自己才能计算出来的值)
签名的生成和校验
生成签名:消息发送者,利用签名密钥,对消息原文进行签名,获得签名
校验签名:消息验证者,利用校验密钥,对签名进行校验。
签名的方法
- 直接对消息签名(不经常使用,签名算法比较慢,消息太大时效率很低)
- 对消息散列值签名
误区
签名不是加密,通过签名,只能保证特定消息,确实是由特定发送者(私钥持有者)发送。一个签名只能验证一个消息
应用场景
- 安全信息报告
- 软件下载
- 公钥证书
- TLS/SSL
数字签名算法
- RSA(最常用)
- EIGamal
- DSA
- Rabin
攻击
- 中间人攻击
防范:保证校验签名的公钥证书的合法性(公钥证书) - 对散列函数攻击
- 利用数字签名攻击公钥密码
公私钥加解密正好和数字签名的校验相反
加解密:公钥加密(密文=消息E次方 mod N),私钥解密(消息原文=密文D次方 mod N)
数字签名:正好进行的是(签名=消息D次方 mod N),正好于私钥解密的步骤一致
防范:不直接对消息原文签名(hash值签名),不公用加解密公私钥和签名公私钥,不对来历不明的消息签名
数字签名无法解决的问题
数字签名可以识别篡改,伪装,还可以防止否认,但是由于需要用到公钥来验证签名,如何保证公钥是合法的。
解决方法:证书(公钥当作消息,由可信的第三方进行数字签名)。又引入了另一个问题,如何对可信的第三方的签名进行校验,需要另一个公钥。从而引入PKI