加密算法
常见的加密算法通常分为分组加密算法和流密码加密算法两种。
分组加密算法基于“分组“(block)进行操作,根据算法的不同,每个分组的长度可能不同。代表有DES、3-DES、Blowfish、IDEA、AES等。
流密码加密算法每次只处理一个字节,密钥独立于消息之外,两者通过异或实现加密与解密。代表有RC4、ORYX、SEAL等。
针对加密算法的攻击,针对攻击者可以获得的信息,可以分为:
唯密文攻击
攻击者有一些密文,它们是使用同一加密算法和同一密钥加密的。
已知明文攻击
攻击者除了能得到一些密文外,还能得到这些密文对应的明文。
选择明文攻击
攻击者不仅能得到一些密文和明文,还能选择用于加密的明文。
选择密文攻击
攻击者可以选择不同的密文来解密。
Stream Cipher Attack
Reused Key Attack
在流密码的使用中,最常见的错误便是使用同一个密钥进行多次加/解密。这将使得破解流密码变得非常简单。这种攻击被称为“Reused Key Attack”,在这种攻击下,攻击者不需要知道密钥,即可还原出明文。
假设有密钥C,明文A,明文B,那么,XOR加密可表示为:
密文是公之于众的,因此很容易就可计算:
因为两个相同的数进行XOR运算结果为0,由此可得:
从而得到了:
这意味着4个数据中,只需要知道3个,就可以推导出剩下的一个。实际应用如下:
Bit-flipping Attack
一个网站应用使用Cookie作为用户身份的认证凭证,而Cookie的值是通过XOR加密而得到的。认证的过程就是服务器端解密Cookie后,检查明文是否合法。假设明文是:
那么当攻击者注册了一个普通用户A时,获取了A的Cookie为Cookie(A),就有可能构造出管理员的Cookie,从而获得管理员权限:
攻击者在不知道明文的情况下,通过改变密文,使得明文按其需要的方式发生改变的攻击方式,称为Bit-flipping Attack。
解决方式是验证密文的完整性,最常见的方法是增加带有KEY的MAC(消息验证码),通过MAC验证密文是否被篡改。
ECB模式的缺陷
分组加密算法有一些通用的加密模式,如ECB、CBC、CFB、OFB、CTR等。
ECB模式(电码簿模式)是最简单的一种加密模式,它的每个分组之间相对独立。但问题出在:攻击者只需要对调任意分组的密文,在经过解密后,所得明文的顺序也是经过对调的。替换某个分组密文,解密后该对应分组的明文也会被替换,而其他分组不受影响。
当需要加密的明文多于一个分组的长度时,应该避免使用ECB模式,而使用其他更加安全的加密模式。
Padding Oracle Attack
针对CBC模式,可以在不知道密钥的情况下,通过对padding bytes的尝试,还原明文,或者构造出任意明文的密文。
密钥管理
密码系统的安全性应该依赖于密钥的复杂性,而不应该依赖于算法的保密性。
密钥管理中最常见的错误,就是将密钥硬编码在代码里。
硬编码的密钥,在以下几种情况下可能被泄露。
- 代码被广泛传播。
- 软件开发团队的成员都能查看代码,从而获知硬编码的密钥。
对于Web应用来说,最常见的做法是将密钥(包括密码)保存在配置文件或者数据库中,在使用时由程序读出密钥并加载进内存。
伪随机数问题
伪随机数不够随机,是程序开发中会出现的一个问题。
很多伪随机数算法与系统时间有关,直接使用系统时间代替随机数的生成,这样生成的随机数是根据时间顺序增长的,可以从时间上进行预测,从而产生安全隐患。
伪随机数是由数学算法实现的,它真正随机的地方在于“种子(seed)”。种子一旦确定后,再通过同一伪随机数算法计算出来的随机数,其值是固定的,多次计算所得值得顺序也是固定的。
在重要或敏感的系统中,一定要使用足够强壮的随机数生成算法。
小结
- 不要使用ECB模式;
- 不要使用流密码(比如RC4);
- 使用HMAC-SHA1代替MD5(甚至是代替SHA1);
- 不要使用相同的key做不同的事情;
- salts与IV需要随机产生;
- 不要自己实现加密算法,尽量使用安全专家已经实现好的库;
- 不要依赖系统的保密性;
- 使用CBC模式的AES256用于加密;
- 使用HMAC-SHA512用于完整性检查;
- 使用带salt的SHA-256或SHA-512用于Hashing。