第11章 加密算法与随机数
1、加密算法
常见的加密算法通常分为分组加密算法与流密码加密算法。
分组加密算法基于“分组”(block)进行操作,根据算法的不同,每个分组的长度可能不同。分组加密算法的代表有:DES、3-DES、Blowfish、IDEA、AES等。
下图演示了一个使用CBC模式的分组加密算法的加密过程:
流密码加密算法,则每次只处理一个字节,密钥独立于消息之外两者通过异或实现加密与解密。流密码加密算法的代表有RC4、ORYX、SEAL等。
下图演示了流密码加密算法的加密过程。
根据攻击者能获取的信息,将加密算法的攻击分为:
- 唯密文攻击:攻击者有一些密文,它们是使用同一加密算法和同一密钥加密的。
已知:
C1=EK ( P1 ),C2=EK( P2 ),……,Ci=EK(Pi)
推导出:
P1,P2,……,Pi,K或者找出一个算法从Ci+1=EK(Pi+1 )推出Pi+1
- 已知明文攻击:攻击者除了能得到一些密文外,还能得到这些密文对应的明文。
已知:
P1,C1=EK ( P1 ),P2, C2=EK(P2 ) ,……, Pi,Ci=EK( Pi) ,
推导出:
密钥k,或从Ci+1=EK(Pi+1 )推出Pi+1
- 选择明文攻击:攻击者不仅能得到一些密文和明文,还能选择用于加密明文。
已知:
P1,C1=EK ( P1 ),P2, C2=EK(P2 ) ,……, Pi,Ci=EK( Pi) ,其中P1,P2,……, Pi是由密码分析者选择的。
推导出:
密钥k,或从Ci+1=EK(Pi+1 )推出Pi+1
- 选择密文攻击:攻击者可以选择不同的密文来解密。
2、Stream Cipher Attack
流密码的加密是基于异或(XOR)操作进行的,每次都只操作一个字节。
3、Reused Key Attack
在流密码的使用中,最常见的错误便是使用同一个密钥进行多次加密/解密。这使得破解流密码变得非常简单,这种攻击称为“Reused Key Attack”,攻击者不需要知道密钥即可还原出明文。
为了增强攻击难度,IV应随机。
4、Bit-flipping Attack
当攻击者在不知道明文情况下,通过改变密文,使得明文按其需要的方式发生改变的攻击方式,被称为Bit-flipping Attack。解决方法是验证密文的完整性:
- 增加带有KEY的MAC(消息验证码,Message Aurhentication Code),通过MAC验证密文是否被篡改。
- HMAC:通过哈希算法来实现MAC。
5、WEP破解
一种最著名的针对流密码的攻击可能就是WEP密钥的破解。
- WEP是一种常用的无线加密传输协议
- 破解了WEP的密钥,可连接Access Point。
- WEP采用RC4算法。
WEP在加密过程中,有两个关键因素
- 初始化向量IV
- 对消息的CRC-32校验
实际破解WEP的步骤(Aircrack实现):
- 加载目标
- 与目标网络进行协商
- 生成密钥流
- 构造ARP包
- 生成自己的ARP包
- 开始破解
- 成功破解出WEP的KEY
6、ECB模式的缺陷
分组加密算法来说,常见的加密模式有:ECB、CBC、CFB、OFB、CTR等。
ECB模式(电码薄模式)是最简单的一种加密模式,它的每个分组之间相对独立,其加密过程:
但问题也在分组上,对调任意分组的密文,经过解密后,得到的明文顺序也是经过对调的。
CBC(链式加密模式)的分组前后之间会互相关联,一个字节变化,会导致整个密文发生变化。
当需要加密的明文多于一个分组的长度时,应该避免使用ECB。
7、密钥管理
密码学有个基本原则:密码系统的安全性应该依赖于密钥的复杂性,而不应该依赖于算法的保密性。
密钥管理中最常见的错误,就是将密钥硬编码在代码里。对于web应用来说,常见的做法是将密钥(包括密码)保存在配置文件或者数据库中。另外,密钥所在的配置文件或数据库需要严格的控制访问权限,同时也要确保运维或DBA中具有访问权限的人越少越好。
8、伪随机数
伪随机数问题:伪随机数不够随机。
伪随机数,是通过一些数字算法生成的随机数,并非真正的随机数。真正的随机数,是通过一些物理系统生成的随机数。
不要把时间函数当成随机数使用,很容易被猜解。
伪随机数是由数学算法实现的,它真正随机的地方在于“种子"(seed)。种子一旦确定后,在通过同一伪随机数算法计算出的随机数,其值是固定的,多次计算所得的值的顺序也是固定的。
9、使用安全的随机数
在重要或者敏感的系统中,一定要使用足够强壮的随机数生成算法。
- 在Java中,使用java.security.SecureRandom
- 在Linux中,使用/dev/random或者/dev/urandom来生产随机数,只需要读取即可。
- php5.3及其以后版本若支持openSSL扩展,可直接使用函数生成随机数。
10、小结
加密算法的最佳实践:
- 不要使用ECB模式
- 不要使用流密码(如RC4)
- 使用HMAC-SHA1代替MD5(甚至代替SHA1)
- 要使用相同的key做不同的事
- salts与IV需要随机产生
- 不要自己实现加密算法,尽量使用安全专家已经实现好的稳定的库
- 不要依赖于系统的保密性
当你不知道该如何选择时,有以下建议:
- 使用CBC模式的AES256用于加密
- 使用HMAC-SHA512用于完整性检查
- 使用带salt的SHA-256或SHA-512用于Hashing