加密算法

常见的加密算法通常分为分组加密算法流密码加密算法两种。

分组加密算法基于“分组“(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的尝试,还原明文,或者构造出任意明文的密文。

密钥管理

密码系统的安全性应该依赖于密钥的复杂性,而不应该依赖于算法的保密性。

密钥管理中最常见的错误,就是将密钥硬编码在代码里。

硬编码的密钥,在以下几种情况下可能被泄露。

  1. 代码被广泛传播。
  2. 软件开发团队的成员都能查看代码,从而获知硬编码的密钥。

对于Web应用来说,最常见的做法是将密钥(包括密码)保存在配置文件或者数据库中,在使用时由程序读出密钥并加载进内存。

伪随机数问题

伪随机数不够随机,是程序开发中会出现的一个问题。

很多伪随机数算法与系统时间有关,直接使用系统时间代替随机数的生成,这样生成的随机数是根据时间顺序增长的,可以从时间上进行预测,从而产生安全隐患。

伪随机数是由数学算法实现的,它真正随机的地方在于“种子(seed)”。种子一旦确定后,再通过同一伪随机数算法计算出来的随机数,其值是固定的,多次计算所得值得顺序也是固定的。

在重要或敏感的系统中,一定要使用足够强壮的随机数生成算法。

小结

  1. 不要使用ECB模式;
  2. 不要使用流密码(比如RC4);
  3. 使用HMAC-SHA1代替MD5(甚至是代替SHA1);
  4. 不要使用相同的key做不同的事情;
  5. salts与IV需要随机产生;
  6. 不要自己实现加密算法,尽量使用安全专家已经实现好的库;
  7. 不要依赖系统的保密性;
  8. 使用CBC模式的AES256用于加密;
  9. 使用HMAC-SHA512用于完整性检查;
  10. 使用带salt的SHA-256或SHA-512用于Hashing。