2013年5月30日星期四

网络安全---加密算法与随机数

网络安全---加密算法与随机数  

2012-08-14 11:13:23|  分类: 网络 |字号 订阅
一、概述
常见的加密算法分为分组加密算法与流密码加密算法。
分组加密算法基于“分组(block)”进行操作,根据算法的不同,每个分组的长度可能不同。分组机密算法的代表有DES、3-DES、Blowfish、IDEA、AES等。
流密码加密算法,每次只处理一个字节,密钥独立于消息之外,两者通过异或实现加密与解密。流密码加密算法的代表有RC4、ORYX、SEAL等。

针对加密算法的攻击,一般根据攻击者能获得的信息,可以分为:
1) 唯密文攻击:攻击者有一些密文,它们是使用同一加密算法和同一密钥加密的。这种攻击是最难的。
2) 已知明文攻击:攻击者除了能得到一些密文外,还能得到这些密文对应的明文。本章中针对流密码的一些攻击为已知明文攻击。
3) 选择明文攻击:攻击者不仅能得到一些密文和明文,还能选择用于加密的明文。
4)选择密文攻击: 攻击者可以选择不同的密文来解密。本章中所提到的“Padding Oracle Attack”就是一种选择密文攻击。

二、Stream Cipher Attack
1、Reused Key Attack
在流密码的使用中,最常见的错误是使用同一个密钥进行多次加密/解密。这将使得破解流密码变得非常简单。这种攻击被称为“Reused Key Attack”,在这种攻击下,攻击者不需要直到密钥,即可还原出明文。
假设有密钥C,明文A和明文B,那么:
E(A)= A xor C
E(B)= B xor C
密文是公之于众的,因此很容易就可计算:
E(A) xor E(B) = ... = A xor B
这意味着4个数据中,住需要知道3个,就可以推导出剩下的一个。这个公式中的C在哪里?已经完全不重要了!
例子:
...

2、Bit-flipping Attack
公式:
A xor E(A) xor B=E(B)
这意味着当知道A的明文、B的明文、A的密文时,可以推导出B的密文。这在实际应用中非常有用。
比如一个网站应用,使用Cookie作为用户身份的认证凭证,而Cookie的值是通过XOR加密而得的。认证的过程就是服务器端解密Cookie后,检查明文是否合法。假设明文是:
username+role
那么当攻击者注册了一个普通用户A时,获取了A的Cookie为Cookie(A),就有可能构造出管理员的Cookie,从而获得管理员权限:
(accountA+member) xor Cookie(A) xor (admin_account+manager)=Cookie(admin)

解决Bit-flipping攻击的方法是验证密文的完整性,最常见的方法是增加带有KEY的MAC,通过MAC验证密文是否被纂改。
通过哈希算法来实现的MAC,称为HMAC。HMAC由于其性能较好,而被广泛使用。
。。。

3、弱随机IV问题
在authcode()函数中,它默认使用了4字节的IV(就是函数中的keyc),使得破解难度增大。但其实4字节的IV是很脆弱的,它不够随机,我们完全可以通过“暴力破解”的方式找到重复的IV。为了验证这一点,调整一下破解程序,如下:
。。。

三、WEP破解
WEP是一种常用的无线加密传输协议,破解了WEP的密钥,就可以以此密钥连接无线的Access Point。WEP采用RC4算法,也存在这两种攻击方式。
WEP在加密过程中,有两个关键因素,一个是初始化向量IV,一个是对消息的CRC-32校验。
。。。
2001 年8月,破解WEP的理论变得可行了。Berkly的Nikita Borisov,Ian Goldberg以及David Wagner共同完成了一篇很好的论文:"Security of the WEP algorithm",其中深入阐述了WEP破解的理论基础。
实际破解WEP的步骤要稍微复杂一些,Aircrack实现了这一过程。
第一步,加载目标:
/home/cg/eric-g# airodump-ng --bssid 00:18:F8:F4:CF:E4 -c 9 ath2 -w eric-gCH 9 ][Elapsed:4 mins][ 2007-11-21 23:08
...
第二步:与目标进行协商
...
第三步:生成密钥流
。。。
第四步:构造ARP包
。。。
第五步:生成自己的ARP包:
...
第六步:开始破解:
。。。
最终成功破解出WEP的KEY,可以免费蹭网了!

四、ECB模式的缺陷
对于分组加密算法来说,除去算法本身,还有一些通用的加密模式,不同的加密算法会支持同样的几种加密模式。常见的加密模式有:ECB、CBC、CFB、OFB、CTR等。如果加密模式被攻击,那么不论加密算法的密钥有多长,都可能不再安全。
ECB模式(电码簿模式)是最简单的一种加密模式,它的每个分组之间相对独立,其加密过程如下:
。。。
但ECB模式最大的问题也是出在这种分组的独立性上:攻击者只需要对调任意分组的密文,在经过解密后,所得明文的顺序也是经过对调的。
这与链式加密模式(CBC)等是完全不同的,链式加密模式的分组前后之间会互相关联,一个字节的变化,会导致整个密文发生变化。这一特点也可以用于判断密文是否是用ECB模式加密的。
对于ECB模式来说,改变分组密文的顺序,其改变解密后的明文顺序;替换某个分组密文,解密后该对应分组的明文也会被替换,而其他分组不受影响。
这是非常危险的,假设某在线支付应用,用户提交的密文对应的明文为:
member=abc||pay=10000.00
其中的前16个字节为:
member=abc||pay=
这正好是一个或两个分组的长度,因此攻击者只需要使用"1.00"的密文,替换"10000.00"的密文,即可伪造支付金额从10000元到1元。在实际攻击中,攻击者可以通过事先购买一个1元物品,来获取1.00的密文,这并非意见很困难的事情。
ECB模式的缺陷,并非某个加密算法的问题。此外,ECB模式仍然会带有明文的统计特征,因此在分组较多的情况下,其私密性也会存在一些问题,如下:
ECB模式并未完全混淆分组间的关系,因此当分组足够多时,仍然会暴漏一些私密信息,而链式模式则避免了此问题。

当需要加密的明文多于一个分组的长度时,应该避免使用ECB模式。

五、Padding Oracle Attack
在Eurocrypt 2002大会上,Vaudenay介绍了针对CBC模式的”Padding Oracle Attack“。它可以在不知道密钥的情况下,通过对padding bytes的尝试,还原明文,或者构造出任意明文的密文。
下面来看看Paddiing Oracle的原理,在此以DES为例。
分组加密算法在实现加密/解密时,需要把消息进行分组,block的大小常见的有64bit、128bit、256bit等。以CBC模式为例,其实现加密的过程大致如下:
。。。
在这个过程中,如果最后一个分组的消息长度没有达到block的大小,则需要填充一些字节,被称为padding。以8个字节一个block为例。
比 如明文是FIG,长度为3个字节,则剩下5个字节被填充了0x05,0x05,0x05,0x05,0x05 这5个相同的字节,每个字节的值等于需要填充的字节长度。如果明文刚好8个字节,如PLANTAIN,则后面需要填充8个字节的padding,其值为 0x08。这种填充方法,遵循的是最常见的PKCS#5标准。
。。。
密文的长度为24个字节,可以整除8而不能整除16,因此可以很快判断出分组的长度为8个字节。
。。。
在解密完成后,如果最后的padding值不正确,解密程序往往会抛出异常(padding error),而利用应用的错误回显,攻击者往往可以判断出padding是否正确。
所以Padding Oracle实际上是一种边信道攻击,攻击者只需要直到密文的解密结果是否正确即可,而这往往有许多途径。
比如在Web应用中,如果Padding不正确,则应用程序很可能会返回500的错误;如果padding正确,但解密出来的内容不正确,则可能会返回200的自定义错误。那么,以第一组分组为例,构造IV为8个0字节:
Request: http://sampleapp/home.jsp?UID=0000000000000000F851...
Response: 500
此时在解密时padding是不正确的。
因此慢慢调整IV的值,以希望解密后,最后一个字节的值为正确的padding byte,比如一个0x01
Request: http://sampleapp/home.jsp?UID=0000000000000001F851...
Response: 500
...
Request: http://sampleapp/home.jsp?UID=000000000000003CF851...
Response: 200 OK

通过XOR 运算,可以马上推导出此Intermediary Byte的值:
。。。
然后遍历IV的第七个字节。
。。。
很快就可以通过XOR运算得到可以生成任意明文的IV。
。。。
Brian Holyfield实现了一个叫padbuster的工具,可以自动实施Padding Oracle攻击。
。。。

Padding Oracle Attack的关键在于攻击者能够获知解密的结果是否符合padding。在实现和使用CBC模式的分组加密算法时,注意这一点即可。

六、密钥管理
在密码学里有个基本的原则:密码的安全性应该依赖于密钥的复杂性,而不应该依赖于算法的保密性。
在安全领域里,选择一个足够安全的加密算法不是困难的事情,难的是密钥管理。直接攻击加密算法的案例很少。对于攻击者来说,他们不需要正面破解加密算法,如果能通过一些方法获得密钥,则是件事半功倍的事情。

密钥管理中最常见的错误,就是将密钥硬编码在代码里。
对于Web应用来说,常见的做法是将密钥(包括密码)保存在配置文件或者数据库中。

七、伪随机数问题
问题是伪随机数不够随机。
真随机数是通过一些物理系统生成的随机数。比如电压的波动、硬盘磁头读/写时的寻道时间、空中电磁波的噪声等。

1、弱伪随机数的麻烦
2、时间真的随机吗?
3、破解伪随机数算法的种子:
4、使用安全的随机数:
在重要或敏感的系统中,一定要使用足够强壮的随机数生成算法。在Java中,可以使用java.security.SecureRandom,比如:
SecureRandom sr=SecureRandom.getInstance("SHA1PRNG");
byte[] bytes=new byte[1024/8];
sr.nextBytes(bytes);

int seedByteCount=10;
byte[] seed=sr.generateSeed(seedByteCount);

sr=SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
....

八、小结:
1、不要使用ECB模式。
2、不要使用流密码(比如RC4)
3、使用HMAC-SHA1代替MD5
4、不要使用相同的key做不同的事情
5、salts与IV需要随机产生
6、不要自己实现加密算法,尽量使用安全专家已经实现号的库
7、不要依赖系统的保密性。

当你不知道该如何选择时,有以下建议:
1、使用CBC模式的AES256加密
2、使用HMAC-SHA512用于完整性检查
3、使用带Salt的SHA-256或SHA-512用于Hashing。

没有评论:

发表评论