1、概述
常见的加密算法:
分组加密算法:DES、3-DES、Blowfish、IDEA、AES等
流密码加密算法:每次只处理一个字节,密钥独立于消息之外,两者通过异或实现加密与解密,RC4、ORYX、SEAL等
2、流密码
1)Reused Key Attack:流密码最常见的错误就是使用同一密钥进行多次加/解密,攻击者者不需求知道密钥即可还原明文。
解决办法:为了增加破解难度,引入了初始化向量,使用随机的初始化向量,以实现一次一密,明文每次加密后产生的密文都不同。初始化向量本身不需要保证其私密性。
2)Bit-flipping Attack:攻击者不知道明文的情况下,通过改变密文,是的明文按其需要的方式发生改变的攻击方式。
解决办法:验证密文的完整性,最常见的方法是增加带有key的MAC(Message Authentication Code),通过MAC验证密文是否被篡改。
通过哈希算法来实现的MAC,成为HMAC。
3)弱随机IV问题
authcode()函数中,默认使用4字节的IV(就是函数中的keyc),使得破解难度增大,但其实4字节的IV是很脆弱的,它不够随机,容易被暴力破解。
3、WEP破解
WEP是一种常见的无线加密传输协议,采用RC4算法,同样存在上述两种流密码攻击漏洞。
4、ECB模式的缺陷
对于分组加密算法,除去算法本身,还有一些通用的加密模式。如果加密模式被攻击,那么不论加密算法的密钥有多长,都可能不再安全。常见的加密模式:ECB、CBC、CFB、OFB、CTR等。
ECB模式最大的问题出在其分组的独立性,攻击者只需要对调任意分组的密文,在经过解密后,所得明文的顺序也是经过对调的;替换某个分组密文,解密后该对应分组的明文也被替换。
CBC:链式加密,分组前后之间会相互关联,一个字节的变化会导致整个密文发生变化。
此外,ECB模式仍会带有明文的统计特征,在分组较多的情况下,其私密性也存在问题。
当需要加密的明文大于一个分组的长度时,应避免使用ECB模式。
5、Padding Oracle Attack
针对CBC模式的Padding Oracle Attack,可以在不知道密钥的情况下,通过对padding gytes的尝试,还原明文,或者构造出任意明文的密文。
Padding Oracle Attack的关键在于攻击者能够获知解密的结果是否符合padding。
6、密钥管理
密码系统的安全性应依赖于密钥的复杂性,而不应该是算法的保密性。
密钥管理中最常见的错误就是将密钥硬编码在代码里;同样,将加密密钥、签名的salt等key硬编码在代码中,也是非常不好的习惯。
硬编码的密钥在以下几种情况下可能被泄露:
1)代码被广泛传播;
2)软件开发团队的成员都能查看代码。
常见的做法是将密钥保存在配置文件或数据库中,使用时由程序读出密钥并加载进内存,密钥所在的配置文件或数据库需要严格的控制访问权限。
密钥管理的主要目的是防止密钥从非正常的渠道泄露,定期更换密钥是一种有效的做法。
一个比较安全的密钥管理系统,可以将所有的密钥的集中保存在一个服务器(集群)上,通过web service的方式提供获取密钥的API。每个应用在需要使用密钥时,通过带认证信息的API请求密钥管理系统,动态获取密钥。应用不能把密钥写入本地文件,只能加载到内存。密钥集中管理,降低了系统对密钥的耦合性,也有利于定期更换密钥。
7、伪随机数问题
伪随机数问题:伪随机数不够随机。
OpenSSL包中存在弱伪随机数算法、时间不能作为随机数、伪随机数算法的种子可能被破解。
需要使用安全的随机数:
JAVA:java.security.SecureRandom
Linux:/dev/random /dev/urandom
PHP5.3.0及其之后的版本,若支持openSSL扩展,则可以直接使用函数来生成随机数。
通过多个随机数的组合,以增加随机数的复杂性。
8、加密算法的选择和使用上的最佳实践:
1)不要使用ECB模式
2)不要使用流密码(比如RC4)
3)使用HMAC-SHA1代替MD5(甚至代替SHA1)
4)不用使用相同的key做不同的事情
5)salt与IV要随机产生
6)不要自己实现机密算法,尽量使用安全专家意见实现好的库
7)不要依赖系统的保密性
具体建议:
1)使用CBC模式的AES256用于加密
2)使用HMAC-SHA512用于完整性检查
3)使用带salt的SHA-256或SHA-512用于Hashing