设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 运营中心 > 建站资源 > 策划 > 正文

对称加密与攻击案例分析

发布时间:2019-06-12 12:14 所属栏目:20 来源:有价值炮灰
导读:本文主要介绍常见的对称加密算法和它们的原理,然后分析一些实际存在的密码学攻击案例,包括流加密密钥重用漏洞、ECB块重排攻击以及CBC的Padding Oracle攻击等。 一、对称加密 当今我们所使用的加密算法,大致可以分为两类,即对称加密与非对称加密。其中

本文主要介绍常见的对称加密算法和它们的原理,然后分析一些实际存在的密码学攻击案例,包括流加密密钥重用漏洞、ECB块重排攻击以及CBC的Padding Oracle攻击等。

对称加密

一、对称加密

当今我们所使用的加密算法,大致可以分为两类,即对称加密与非对称加密。其中对称加密所能加密的内容长度一般受密钥长度的限制,且加密速度较慢,因此通常会与对称加密算法结合使用,即使用对称加密来对明文进行加密,再使用私钥对对称加密的密钥进行加密。本文主要关注对称加密。

对称加密在消息通信的两端共享相同密钥,加密算法一般分为两种类型:

  • 流加密(Stream Ciphers):逐字节加密数据
  • 块加密(Block Ciphers):逐块加密数据

其中块加密的块大小与具体加密算法的实现有关,常见的块大小有128、256位等。

1. 流加密

流加密会逐字节加密数据,最常见的流加密算法就是SSL中用到的RC4算法了。其本质上是以密钥为种子(seed)产生的随机数来对明文进行逐字节异或。

  1. 0 xor 00 = 0 
  2. 0 xor 11 = 1 
  3. 1 xor 0 = 1 
  4. 1 xor 1 = 0 

流加密本质上依赖于随机数生成器的随机性,其随机性越强,加密强度就越大。

2. 块加密

块加密也称为分组加密,也是大多数人比较熟悉的。AES、DES、3DES、Towfish等常见的加密算法都是块加密。在块加密中,原始数据会被分割成若干个大小为N的块,并分别对这些块进行加密。由于我们不能保证数据是N的倍数,因此需要对数据进行填充(Padding),这增加了实现的复杂度。一般来说,与流加密相反,块加密的解密流程和加密流程往往是不同的。

二、Padding

一种常见的填充方式是不论数据大小是否对齐块边界,都进行填充,而填充的内容为填充的字节数。比如块大小为8字节,那么可能有以下填充:

  1. ‘AAAAAAA’ + ‘\x01’  
  2. ‘AAAAAA’ + ‘\x02\x02’  
  3. …  
  4. ‘AA’ + ‘\x06’ * 6  
  5. ‘A’ + ‘\x07’ * 7  
  6. ‘\x08’ * 8 

这就是PKCS#7中所定义的填充方式。

三、加密模式

块加密算法对数据进行逐块加密,有很多加密模式(mode)用于实现块的加密。这些加密模式大都可以归类为两种,即ECB模式和CBC模式。

1. ECB

ECB全称为Electronic CodeBook,是块加密中比较简单的加密模式。在ECB模式中,每一块明文数据都被独立地进行加密来生成加密块。这意味着如果你发现两个加密块有相同的内容,那么就可以确定这两个加密块的原文也是相同的。

这看起来好像没什么大不了的,但我们可以考虑这么一种情况,比如要加密的对象是一张图像,我们使用ECB加密算法,并且设置块大小为8字节(DES),加密后的图像如下:

tux.png

虽然和原图有所区别,但也足以明显地看出原图的大致内容。

2. CBC

CBC全称为Cipher-Block Chaining,算是最常见的块加密模式了。在CBC模式中,每个明文块都会在加密前被使用前一个明文块的秘文进行异或;解密过程则正好相反。其中第一个明文块会被使用IV即初始化向量进行异或。

cbc.png

由于CBC模式中各个块会相互链接,在第一个加密块(Block0)中翻转某一位,则会在解密后导致对应的下一个明文块中(Block1)相同的位进行翻转。这项特性也导致了许多有趣的bug,后面会说到。

四、常见攻击

下面我们来介绍一下在现实中很常见的一些加密算法缺陷所导致的攻击场景。

1. 流加密重用攻击

也常称为Stream Cipher Reuse Attack,指多次使用相同的流加密密钥可导致明文泄露。前面说过,流加密实际上是使用密钥生成随机序列,然后用该序列来对明文逐位异或加密。假设生成的随机序列为C(K),加密函数为E(),那么对于明文A、B来说,则:

  1. E(A) = A xor C 
  2. E(B) = B xor C 

进行简单的数学运算:

  1. E(A) xor E(B) = (A xor C) xor (B xor C) = A xor B xor C xor C = A xor B 

这意味着如果攻击者可以拿到A、B的密文E(A)、E(B),以及攻击者自己的明文B,就可以在无需知道密钥的情况下计算出A的明文:

  1. A = E(A) xor E(B) xor B 

眼见为实,我们使用RC4流加密为示例,首先使用openssl生成两个文件的密文(使用相同密钥):

  1. $ cat 1.txt 
  2. hello 
  3. $ cat 2.txt 
  4. world 
  5.  
  6. $ openssl rc4 -nosalt -in 1.txt > 1.enc 
  7. $ openssl rc4 -nosalt -in 2.txt > 2.enc 

接着,在已知1.enc、2.enc以及2.txt的情况下,还原1.txt的内容:

  1. #!/usr/bin/env python3 
  2.  
  3. def load(file): 
  4.     with open(file, 'rb') as f: 
  5.         data = f.read() 
  6.     print('loaded', len(data), 'bytes from', file) 
  7.     return data 
  8.  
  9. def xor(lhs, rhs): 
  10.     return bytes(a ^ b for a, b in zip(lhs, rhs)) 
  11.  
  12. #  A = load('./1.txt') 
  13. A_enc = load('./1.enc') 
  14. B = load('./2.txt') 
  15. B_enc = load('./2.enc') 
  16.  
  17. print('E(A) =', A_enc) 
  18. print('E(B) =', B_enc) 
  19. print('B =', B) 
  20. print('A =', xor(xor(B, B_enc), A_enc)) 

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读