密码技术

密码工具箱包括如下几种技术

  • 对称密码:DES,AES等
  • 公钥密码(非对称密码):RSA等
  • 单向散列函数(哈希函数):SHA-256,MD5等
  • 消息认证码:HMAC
  • 数字签名:RSA
  • 伪随机数

对称密码

加密和解密用的是同一组密钥。常见的对称加密算法有,DES,3DES,AES等。

DES:以64位分组对数据加密,密钥长度56位。目前已经被破解,不推荐使用。 3DES:顾名思义,3重DES。采用3个密钥对分组进行加密。 AES:高级加密算法标准。来自于选拔,从众多加密算法中,经过评比等方式,选出最优的加密算法,作为标准。最终选中Rijndael算法。同样是分组加密模式。

分组密码模式

前面提到了分组加密。指的是,一般对称加密每次加密只能处理固定的长度。当原始数据超过了这个长度时,则需要将数据划分为多个分组进行迭代加密。分组迭代加密的方式即分组密码模式,分为如下几种

  • ECB

Electronic CodeBlock mode,电子密码本模式。此模式,明文分组加密后直接成为密文分组,一一对应。解密也是。此模式比较简单。

攻击者可以不必知道解密方式即可进行攻击。例如,有一个明文记录一个3元组(甲方,转账100,乙方)。攻击者无需破解密文,只需要调整密文的顺序,即可伪造一个(乙方,转账100,甲方)的消息。

  • CBC

Cipher Block Chaining mode,密码分组链接模式。将前一个明文加密后的密文与当前明文混合起来加密。后一个加密依赖前一个分组,链式的。第一个分组不存在前一个分组,所以,需要生成一个初始化向量。

特点是需要知道每个分组的完整内容,才能得到明文。如果有一个分组损坏,都无法完成解密。

初始化向量攻击。因为针对密文攻击,改变其中一个比特位,造成的影响太大。所以,针对向量攻击,会相对简单。因为,最终的明文都和向量进行xor操作。如果反转向量的某一位,则对应的明文也会反转。攻击方可以利用这一点。

填充提示攻击。因为分组长度不够时,会填充一部分数据凑整。攻击者反复发送修改了某几个填充位的密文,针对服务器的错误信息获取关于部分明文的信息。这种攻击不仅仅存在于CBC。

  • CFB

Cipher FeedBack mode,密文反馈模式。类似于CBC,不过是将前一个密文分组加密后xor当前分组。将密文加密的密钥来自于随机加密密钥算法。

CFB模式可以采用重放攻击。A个B发送一个4个分组的密文。攻击人记录下其中的后3个密文。当下次A给B发送时,B替换其中的后3个为之前的3个。根据CFB逻辑,第一个分组可以正常解密,第二个分组解密失败,后2个分组解密成功。

  • OFB

Output FeedBack mode,输出反馈模式。将明文分组和密码算法的输出进行xor产生密码分组。

  • CTR

CounTeR mode,计数器模式。每个分组对应于一个逐次累加的计数器。计数器加密后再xor明文得到密文。

一个完整的对称加密算法,需要包含如上所诉的内容。例如,aes-128-cbc,即是采用aes算法,分组长度128位,cbc分组模式进行加密。对称加密中,密钥的传输也是安全隐患。

公钥密码

公钥密钥,也叫非对称加密。和对称加密不同,他是由算法和一组密钥对组成。密钥对分为公私钥。公钥是公开的,每个人都能获取,私钥只有解密方才有。当进行通信时,采用公钥加密数据,这时候,只要持有私钥的那一方,才能够完成解密。

非对称更加安全,它解决了对称加密密钥传输的问题。但是也有安全隐患,即,不确定自己手上持有的公钥是不是正确的。例如,A和B采用非对称加密通信,B拿到公钥,加密数据,发送给A。如果A和B通信被劫持,B拿到的是伪造的公钥,那么,他的数据会被劫持方拿到,劫持方用自己的私钥解密。

常见的非对称加密算法有:RSA,椭圆曲线等。

RSA算法

生成公私钥过程如下

  1. 随机两个比较大的素数p和q,计算N=pq。
  2. 根据欧拉函数,就得r=Φ(N)=(p-1)(q-1)。
  3. 选择一个小于r的整数,使得e与r互质。并求e关于r的模逆元,命名为d。即ed%r=1。
  4. 将p和q销毁。

(N, e)即为公钥,(N, d)即私钥。

加密解密通信如下

明文^e % N = 密文

密文^d % N = 明文

RSA算法很简单,有严格的数学证明。它并不是不可破解,而是破解需要的计算量非常大,所以才显得安全。

对RSA进行密文攻击。例如,黑客是知道密文,N和e的。能不能按照加密的过程,根据这3个信息,求出明文的值呢?这就涉及到求离散对数的问题。

暴力求解d。能不能根据ed%r=1来暴力求解d呢?此处,即是求p和q。最终变成对N进行分解质因数。目前没有一个高效的方式来完成这个事情。

所以,目前而言,RSA还是比较安全的。

那既然非对称加密算法这么优秀,为什么不在所有需要通信的地方都用这种方式呢。首先它更加复杂,其次,相比对称加密,它的计算速度更加慢。所以,非对称加密一般用于传输对称加密密钥之类的数据。

单向散列函数

对原始数据计算一组摘要。可用于验证数据的完整性,没有被篡改。例如,网站下载的文件会附带一个sha-256摘要,用户可以通过对比摘要来判断下载的文件是不是正确的。

常见的散列函数有:MD5,sha-256等。

散列函数也叫哈希函数,特点有

  • 单向
  • 不管源文件多长,散列值一般固定长度
  • 计算速度很快
  • 消息不同,散列值也不同

散列函数的一个性质是,抗碰撞性。因为散列值的长度是固定的,当散列的数据足够多,是很可能会发生散列值相同的情况的。此时,就比较危险;此外,还有一些细节。例如,改变源文件一个比特位,如果散列值的变化非常小。那么也有可能被找到突破口。哈希雪崩,就是指,当改变一个比特位,结果的散列值完全不同这种现象。

哈希攻击

哈希攻击主要有暴力破解和生日碰撞。

暴力破解,顾名思义就是随机生成数据来匹配散列值。有些文件会有冗余数据,通过不断填充冗余数据来暴力破解。

生日碰撞,本质是一个数学概率问题。假设一个教室有N个人,若保证这N个人至少2人生日相同,此时N最少是多少?惯性思维,可能会觉得是366。实际上,远少于这个数字。可以反过来理解,算算N个人生日完全不同的概率,然后用1减去这个值。

完全不同的概率

x = (364*363*362…*1)/(365*365*365…*365)

最后,生日相同的概率

1-x

计算发现,当N取70时,生日相同的概率已经达到了99%。概括来说,生日为固定某一天的概率相同和任意某一天生日概率相同,N的取值差别很大。针对哈希的生日碰撞攻击,假设一个32位的哈希算法。理论上有2^32种可能,但是实际上,找到相同散列值需要尝试的次数比这个小多了。

散列值只是确定了文件内容的正确性。但是依然不能保证,你收到的数据是来自于真正的发送方。

消息认证码

消息认证码是一种和密钥关联的单向散列函数。HMAC有一套自己的计算规则,只是并没有限制其中的单向散列函数。例如,HMAC-SHA-256,即是在计算HMAC时,采用SHA-256散列函数。

攻击者可以采用,重放攻击,密钥推测攻击等手段。

消息认证码依然存在对称加密的密钥传输问题。此外,还存在第三方无法证明的情况。例如,假设,A和B进行通信,由第三方C进行密钥托管。当B收到HMAC时,他不知道是A还是C发送的,理论上C是有能力发送的。

数字签名

数字签名采用非对称加密的方式,来实现认证。由发送方使用私钥生成一个签名,然后接收方用公钥去验证这个签名。和之前提到的公私钥通信方式相反。

数字证书

前面提到了非对称加密的一个安全问题,就是,无法确认自己收到的公钥是准确的。数字证书就可以解决这个问题。组织个人将自己的公钥,向数字认证机构,申请一份证书。证书机构用自己的私钥加密申请的公钥,生成一个密文,附加上其他信息即为一个证书。

当用户拿到这个证书时,即可用组织机构的公钥去解密证书,然后和收到的公钥进行比对,看是否一致。一致即表明是对方发送的。

数字证书也有安全隐患,即依赖数字认证机构的可靠。如果认证机构被黑客攻击,黑客给自己的公钥颁发一个证书,那就麻烦了。

随机数

随机数在密码技术中还是很重要的。观察各种加密算法时,可以发现密钥生成等,都和随机数有关系。如果随机数生成算法不够优秀,则攻击者可针对随机数进行攻击。找到随机数规律,那样,破解的难度将会大大降低。

随机数性质有:随机性,不可预测性,不可重现性。按照这三个性质,随机数可以分为,弱伪随机数,强伪随机数,真随机数。

试想下,将一个掷骰子的过程机械化?筛子有一个初始状态,哪面朝上等,这就是种子。给筛子施加一个力,即可得到一个最终面,这是随机数算法。如果,采用机器掷骰子,相同的初始状态,相同的力,很可能得到相同的结果。这就不随机了。

密钥交换

前面提到了各种各样的密钥

  • 对称加密中的密钥
  • 非对称的公私密钥
  • HMAC中的加密密钥

这些密钥都是加密系统的核心数据。如果密钥被获取了,则整个通信毫无隐私可言了。因此,密钥配送也是一个问题。Diffie-Hellman密钥交换是解决此问题的方式之一。

Diffie-Hellman密钥交换

全称是Diffie-Hellman,简写是DH。它的计算思路和RSA的公私钥类似,利用的是离散对数求解的数学难度。其过程如下

Alice: G^A % P = M
Bob: G^B % P = N

计算密钥
Alice: N^A % P = (G^B % P)^A % P = G^(A*B) % P
Bob: N^B % P = (G^A % P)^B % P = G^(B*A) % P

1. 由Alice或者Bob生成G和P。P是任意很大的质数。G是它的一个生成元,即G的任意乘方结果模P与P-1一一对应。
2. Alice生成任意一个数A,需保密;Bob生成任意一个数B,需保密。
3. Alice计算出M,传递给Bob;Bob计算N传给Alice。
4. Alice和Bob根据对方的数字各自计算出密钥。

DH无法保证前向安全性。所谓前向安全性,即,当攻击者获取了密钥以后,能否解密历史数据。DHE通过临时DH密钥解决了前向安全性问题。

椭圆曲线Diffie-Hellman

全称是Elliptic-curve Diffie-Hellman key exchange,简写是ECDHE。是使用椭圆曲线算法实现的密钥交换。

具体逻辑和数学原理可以参考网上各种资料,这个用的相当广泛。

总结

学习了如上的知识,对密码系统有了一个广义的了解。例如,有程序员会混淆的,MD5和加密函数关系等。另外,在一些协议中,经常出现一长串加密算法名字,看到这个名字现在能知道他表述的含义了。还有,知道各个技术解决的问题,可能被攻击的地方。

HTTPS协议应该算是比较完整的应用了各种加密技术的例子了。可能有必要再重新梳理下了。

参考资料