对称加密和攻击案例分析

发布者:上海IT外包来源:http://www.lanmon.net点击数:2042

本文重点介绍常见的对称加密算法及其原理,然后分析一些实际的加密攻击案例,包括流加密密钥重用漏洞,ECB块重排攻击和CBC的Padding Oracle攻击。
对称加密
首先,对称加密
我们今天使用的加密算法大致可分为两类,对称加密和非对称加密。可以通过对称加密加密的内容的长度通常受密钥长度的限制,并且加密速度慢。因此,它通常与对称加密算法结合使用,即对称加密用于加密明文,然后私钥用于对称加密。密钥已加密。本文重点介绍对称加密。
对称加密在消息通信的两端共享相同的密钥。加密算法一般分为两种类型:
流密码:逐字节加密数据
分组密码:逐块加密数据
块加密的块大小与特定加密算法的实现有关。公共块大小是128,256位等。
流加密
流加密逐字节加密数据。最常见的流加密算法是SSL中使用的RC4算法。它基本上执行明文的逐字节XOR,其中密钥作为种子生成随机数。
0 xor 00=0
0 xor 11=1
1 xor 0=1
1 xor 1=0
流加密主要取决于随机数发生器的随机性。随机性越强,加密强度越大。
2.阻止加密
块加密,也称为块加密,对大多数人来说都很熟悉。常见的加密算法(如AES,DES,3DES和Towfish)是块加密。在块加密中,原始数据被分成大小为N的块,并且块被单独加密。由于我们不能保证数据是N的倍数,我们需要填充数据,这增加了实现的复杂性。通常,与流加密相反,块加密的解密过程和加密过程通常是不同的。
第二,填充
填充的常用方法是填充,无论数据大小是否与块边界对齐,填充的内容是填充的字节数。例如,如果块大小为8个字节,则可能存在以下填充:'AAAAAAA'+'\ x01'
'AAAAAA'+'\ x02 \ x02'
.
'AA'+'\ x06'* 6
'A'+'\ x07'* 7
'\ x08'* 8
这是PKCS#7中定义的填充方法。
三,加密模式
块加密算法逐块加密数据,并且存在许多用于实现块加密的加密模式(模式)。这些加密模式中的大多数可以分为两种类型,ECB模式和CBC模式。
欧洲央行
ECB称为电子CodeBook,是块加密中相对简单的加密模式。在ECB模式中,每个明文数据块被独立加密以生成加密块。这意味着如果您发现两个密码块具有相同的内容,则可以确保两个密码块的原始文本相同。
这似乎没什么大不了的,但我们可以考虑一种情况,即要加密的对象是图像,我们使用ECB加密算法,并将块大小设置为8字节(DES)。加密图像如下:
Tux.png
虽然它与原始图片不同,但足以清楚地看到原始图片的一般内容。
2. CBC
CBC称为密码块链接,这是最常见的块加密模式。在CBC模式中,每个明文块在加密之前使用前一个明文块的secrettext进行异或;解密过程恰恰相反。使用IV或初始化向量对第一个明文块进行异或。
Cbc.png
由于CBC模式中的每个块彼此链接,因此在第一个加密块(块0)中翻转一个位将导致在解密之后翻转相应的下一个明文块(块1)中的相同位。此功能也导致了许多有趣的错误,稍后将对此进行讨论。
第四,常见的攻击
让我们来看看由实际中常见的加密算法的缺陷引起的一些攻击场景。
流加密重用攻击
通常也称为流密码重用攻击,这意味着多次使用相同的流加密密钥可能会导致明文泄漏。如前所述,流加密实际上使用密钥生成随机序列,然后用于按顺序对明文进行异或。假设生成的随机序列是C(K)且加密函数是E(),那么对于明文A和B,则:
E(A)=A x或C.
E(B)=B x或C.
执行简单的数学运算:
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的明文:
A=E(A)x或E(B)xor B.
眼见为实,我们以RC4流加密为例,首先使用openssl为两个文件生成密文(使用相同的密钥):
$ cat 1.txt
你好
$ cat 2.txt
世界
$ openssl rc4 -nosalt -in 1.txt>
1.enc
$ openssl rc4 -nosalt -in 2.txt>
2.enc
接下来,在1.enc,2.enc和2.txt的情况下,恢复1.txt的内容:
#!/usr/bin/env python3
Def load(文件):
打开(文件,'rb')为f:
数据=f.read()
打印('loaded',len(data),'bytes from',file)
返回数据
Def xor(lhs,rhs):
返回字节(a ^ b为a,b为zip(lhs,rhs))
#A=load('./1.txt')
A_enc=load('./1.enc')
B=加载('./2.txt')
B_enc=load('。/2.enc')
打印('E(A)=',A_enc)
打印('E(B)=',B_enc)
打印('B=',B)
打印('A=',xor(xor(B,B_enc),A_enc))
输出:
$ python3 stream.py
从./1.enc加载6个字节
从./2.txt加载6个字节
从./2.enc加载6个字节
E(A)=b'\ xa1 \ xb1` \ x1b \ xa7 \ x97'
E(B)=b'\ xbe \ xbb~ \ x1b \ xac \ x97'
B=b'world \ n'
A=b'hello \ n'在密钥未知的情况下,仍然可以成功恢复1.txt的明文内容。防范此类攻击的方法是尽可能避免重用流加密密钥。常见的实现是在加密之前使用随机数nonce操作密钥。
2. ECB阻止重排攻击
如前所述,ECB模式中的每个块都以块加密方式独立加密。因此,攻击者可以在未知密钥的情况下重新排列密文中的块,并将它们组合成合法可解密的新密文。
考虑到这种情况,CMS的cookie格式是DES-ECB加密数据,明文格式如下:
管理员=0;用户名=锅
由于DES使用的块大小为8字节,因此上述明文可以分为三个块,其中@是填充符号:
管理员=0;
用户名
=平移@@@@
假设我们可以控制自己的用户名(在注册时),有没有办法在不知道密钥的情况下以管理员身份提取自己(即admin=1)?首先将用户名设置为pan @@ @@ admin=1;此时,明文块的内容如下:
管理员=0;
用户名
=平移@@@@
管理员=1;
我们需要做的就是在加密完成后用最后一个块替换第一个块,从而获得具有管理员权限的合法cookie。
完整的例子不完整,这里只是为了证明这种方法的可行性,首先使用DES-ECB加密明文:
$ $ cat admin.txt
管理员=0;用户名=锅
$ openssl des-ecb -nosalt -in admin.txt>
Admin.enc
$ xxd admin.enc
00000000: 0293 07cd 88f3 026e c61e 1284 1a6e 6853 .. n .. nhS
00000010: e0b2 7169 3ee4 0b9a .qi>
.
然后修改密文,替换前两个块(8个字节),然后使用相同的密钥解密:
$ xxd admin1.enc
00000000: c61e 1284 1a6e 6853 0293 07cd 88f3 026e .. nhS .. n
00000010: e0b2 7169 3ee4 0b9a .qi>.
$ openssl des-ecb -nosalt -d -in admin1.enc
Usernameadmin=0;=锅
可以看出,攻击方法确实对ECB块加密算法有效。
类似的利用方法是在能够解密的情况下将其他密文的相应块替换为它们自己的密文块,从而获得其他密文块的明文数据。例如,如果上述示例可以通过cookie获取用户名,则可以在用户名部分中放置其他密文块以获得其他加密信息。
这种攻击和其他类似的攻击实际上有一个共同点。我们无法获取和猜测原始数据,但我们可以修改密文数据并让服务器成功解密。因此,攻击方法应该是显而易见的,即加密后添加MAC检查。
请注意,这是首先加密的MAC。如果顺序颠倒,则需要在处理数据时解密然后验证MAC。这可能会导致一系列安全问题,例如下面提到的密文填充(Padding Oracle)攻击。
3.填充Oracle攻击
在介绍攻击之前,您可以查看有关填充的知识。在PKCS#7系统中,我们可以知道填充的大小以及最后一个块的最后一个字节的检查填充是否合法。
填充Oracle攻击通常发生在CBC块加密模式和PKCS#7填充中。如果服务器在解密数据时填写合法密文和填写非法密文的回报不同,我们可以使用此先验知识(Oracle)来填充数据。
回想一下,当我们引入CBC块加密时,在加密块(块N)中翻转一个位将导致在解密之后翻转相应的下一个明文块(块N + 1)中的相同位。由于此功能,我们可以使用服务器在不知道密钥的情况下猜测明文数据。
IT外包
>
400-635-8089
立即
咨询
电话咨询
服务热线
400-635-8089
微信咨询
微信咨询
微信咨询
公众号
公众号
公众号
返回顶部