CBC加密原理及攻击
原理
基于分组加密
加密过程
Plaintext:明文,待加密的数据。
IV:用于随机化加密的比特块,保证即使对相同明文多次加密,也可以得到不同的密文,初始向量,用来与第一块的明文异或运算。
Key:被一些如AES的对称加密算法使用。
Ciphertext:密文,加密后的数据。
在这里重要的一点是,CBC工作于一个固定长度的比特组,将其称之为块。在本文中,我们将使用包含16字节的块。
• Ciphertext-0 = Encrypt(Plaintext XOR IV)—只用于第一个组块
• Ciphertext-N= Encrypt(Plaintext XOR Ciphertext-N-1)—用于第二及剩下的组块
XOR为异或运算 , N为第N块数据
---------------------------------------------------------------------------
上述的公式和图可以简单描述为:
1.将要CBC加密的数据分为N个块,每个块为16字节
2.随机找一个IV(初始向量),大小为每个块的大小(16字节),用于与第一个块进行异或运算
3.将异或运算的结果进行选定的加密方式进行加密
4.将得到的第一块密文与第二块明文进行异或运算
5.将异或运算的结果进行选定的加密方式进行加密
6.将得到的第二块密文与第三块明文进行异或运算
7.将异或运算的结果进行选定的加密方式进行加密
8.最后得到三块加密获得的密文
注意:正如你所见,前一块的密文用来产生后一块的密文。
----------------------------------------------------------------------
解密过程
Decryption Process
• Plaintext-0 = Decrypt(Ciphertext) XOR IV—只用于第一个组块
• Plaintext-N= Decrypt(Ciphertext) XOR Ciphertext-N-1—用于第二及剩下的组块
• -----------------------------------------------------------------------------------
上述的公式和图可以简单描述为:
1.将已经CBC加密的数据分为N个块,每个块为16字节
2.将第一块加密的数据用选定的加密方式解密
3.找到加密时的IV,用于与第一个解密后的块进行异或运算,得到第一块的明文
4.将第二块加密数据进行解密
5.用第一块加密的密文与第二块解密的块进行异或运算,得到第二块的明文
6.将第三块加密的数据进行解密
7.用第二块加密的数据与第三块解密的块进行异或运算,得到第二块的明文
通过上述的解密过程可以推算出:
如果要修改第二个块中的第n个字节的数据,只要修改第一块数据的密文中的第n个字节数据,这样第一个块的密文与第二个块解密得到的数据进行异或运算时就可以得到自己想要的数据,对第三个块及其以后的数据都不会产生影响(因为与下一块进行异或运算的都是加密的数据,第二块的加密数据没有进行改变),但是第一个块修改了加密数据,进行解密和与IV异或运算后会产生错误数据。
以此类推,如果要修改第三块中的数据,就修改第二块的加密信息,会产生错误数据的只有第二块数据,其他块的数据不会产生错误。
如果要修改第一块的数据的话,只能修改第一块密文,这需要知道IV是什么,过程:
1.将第一块的明文修改成想要的数据
2.将修改完的数据与IV进行异或运算,然后进行选定方式的加密,得到密文数据
3.将第一块的密文数据换成的到的密文数据
这样的话会出现错误的块是第二块,因为第一块的密文修改了,与第二块的已解密的数据进行异或运算时产生错误。
解决错误的方式是修改IV
-----------------------------------------------------------------------------
注意:Ciphertext-N-1(密文-N-1)是用来产生下一块明文;这就是字节翻转攻击开始发挥作用的地方。如果我们改变Ciphertext-N-1(密文-N-1)的一个字节,然后与下一个解密后的组块异或,我们就可以得到一个不同的明文了!You got it?别担心,下面我们将看到一个详细的例子。与此同时,下面的这张图也可以很好地说明这种攻击:
0x02 一个例子(CBC Blocks of 16 bytes)
比方说,我们有这样的明文序列:
a:2:{s:4:"name";s:6:"sdsdsd";s:8:"greeting";s:20:"echo 'Hello sdsdsd!'";}
我们的目标是将“s:6”当中的数字6转换成数字“7”。我们需要做的第一件事就是把明文分成16个字节的块:
• Block 1:a:2:{s:4:"name";
• Block 2:s:6:"sdsdsd";s:8
• Block 3::"greeting";s:20
• Block 4::"echo 'Hello sd
• Block 5:sdsd!'";}
因此,我们的目标字符位于块2,这意味着我们需要改变块1的密文来改变第二块的明文。
有一条经验法则是(注:结合上面的说明图可以得到),你在密文中改变的字节,只会影响到在下一明文当中,具有相同偏移量的字节。所以我们目标的偏移量是2:
• [0] = s
• [1]= :
• [2] =6
因此我们要改变在第一个密文块当中,偏移量是2的字节。正如你在下面的代码当中看到的,在第2行我们得到了整个数据的密文,然后在第3行中,我们改变块1中偏移量为2的字节,最后我们再调用解密函数。
1. $v = "a:2:{s:4:"name";s:6:"sdsdsd";s:8:"greeting";s:20:"echo 'Hello sdsdsd!'";}";
2. $enc = @encrypt($v);
3. $enc[2] = chr(ord($enc[2]) ^ ord("6") ^ ord ("7"));
4. $b = @decrypt($enc);
运行这段代码后,我们可以将数字6变为7:
但是我们在第3行中,是如何改变字节成为我们想要的值呢?
基于上述的解密过程,我们知道有,A = Decrypt(Ciphertext)与B = Ciphertext-N-1异或后最终得到C = 6。等价于:
C = A XOR B
所以,我们唯一不知道的值就是A(注:对于B,C来说)(block cipher decryption);借由XOR,我们可以很轻易地得到A的值:
A = B XOR C
最后,A XOR B XOR C等于0。有了这个公式,我们可以在XOR运算的末尾处设置我们自己的值,就像这样:
A XOR B XOR C XOR "7"会在块2的明文当中,偏移量为2的字节处得到7
--------------------------------------------------------------------
异或计算的公式:
1.A XOR B =C , B XOR C=A, A XOR C =B
2.A XOR B XOR C =0
3.0 XOR A = A
----------------------------------------------------------------
Demo
目前自己测试只能修改第二块和第一块数据
源码:
function login($info){
$iv = get_random_iv();
$plain = serialize($info);
$cipher = openssl_encrypt($plain, aes-128-cbc, SECRET_KEY, OPENSSL_RAW_DATA, $iv);
$_SESSION['username'] = $info['username'];
setcookie("iv", base64_encode($iv));
setcookie("cipher", base64_encode($cipher));
}
function check_login(){
if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){
$cipher = base64_decode($_COOKIE['cipher']);
$iv = base64_decode($_COOKIE["iv"]);
if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){
$info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>");
$_SESSION['username'] = $info['username'];
}else{
die("ERROR!");
}
}
}
if(isset($_POST['username']) && isset($_POST['password'])){
$username = (string)$_POST['username'];
$password = (string)$_POST['password'];
if($username === 'admin'){
exit('<p>admin are not allowed to login</p>');
}else{
$info = array('username'=>$username,'password'=>$password);
login($info);
show_homepage();
}
else{
if(isset($_SESSION["username"])){
check_login();
show_homepage();
}
输入用户名admir密码1,抓取数据内容为:
Cookie:
PHPSESSID=iq1lrnq2fhp235ndd4ke2njl73;
iv=XyP2qyLI00SzmCP8t766mA%3d%3d;
cipher=8Rhxwqez6NPucPx4mKM4oytL0QCEM6YnRhjkPTjIVvDMp8HAF2%2f8JjiWG8oSLqwgdGs4EV018W7SU63K3bYV9w%3d%3d
过程: XOR异或 、CRYPT加密(未知密钥)、en-加密后
plain XOR iv ->after_plain CRYPT ->en-after_plain
补充:AES加密后的数据为16字节的整数倍,可直接进行异或运算
解题过程:
<?php
$enc=base64_decode("bIpgPK29vVQosJ+smzh0pOdq7QrP3H9CN0MBfynL1eKtILs/ayew1snTYbeYSIz8rQctkAUMORS76SWQHXwuKg==");
$enc[13] = chr(ord($enc[13]) ^ ord("k") ^ ord ("n"));
echo base64_encode($enc);
?>
<?php
$enc=base64_decode("4quudO++PAeVPQfcFJ0bbm1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjM6IjEyMyI7fQ==");
$iv=base64_decode("TrphJjWLH37sj6+EBqh28A==");
$cleartext = 'a:2:{s:8:"userna';
$newiv = '';
for ($i=0;$i<16;$i++){
$newiv=$newiv.chr(ord($iv[$i]) ^ ord($enc[$i]) ^ ord ($cleartext[$i]));
}
echo base64_encode($newiv);
?>
详解:
1. $enc = en-after_plain
2. 因为序列化的内容为
a:2:{s:8:"userna
me";s:5:"admik";
s:8:"password";s
:1:"1";}
所以修改块二上的第13位数据(从0开始),因此修改块一13位数据(AES加密)
3. 修改数据计算:
1.算法
ciphertext XOR plaintext = 加密前xor后的plain
加密前xor后的plain XOR plaintext =ciphertext
所以比如要修改enc[23]处的值时,使用的算法为enc[7]^"替换前"^"替换后"
注意错误:不能使用加密后直接异或,从过程来看就为错误
例如enc[23]^"H"就是错误的,因为加密后原本异或后位置的字符改变
2.关于改变后iv的获得
由于数据改变导致第一块数据异或时得到不能序列化的数据,所以需要根据网页返回的不能序列化的数据(也就是除iv修改完后块一的数据,base64解码后就是序列化数据)进行异或运算来的得到新的iv
与前面的1 运算相同
iv XOR 网页返回的数据 = 加密前xor后的plain(序列化错误的)
加密前xor后的plain XOR plain(正常序列的) = new_iv
所以得到iv算法为 iv ^ wrong_plain ^ plain
补充:由于加密解密得关系 所以不只是特定位置的字符错误,需要全部异或计算
CBC加密原理及攻击的更多相关文章
- 分组密码CBC加密缺陷
title: 分组密码CBC加密缺陷 date: 2017-05-15 10:04:47 tags: ["密码学"] --- 关于密码学的种种漏洞以及利用网上也有不少,但是比较零散 ...
- Atitit RSA非对称加密原理与解决方案
Atitit RSA非对称加密原理与解决方案 1.1. 一.一点历史 1 1.2. 八.加密和解密 2 1.3. 二.基于RSA的消息传递机制 3 1.4. 基于rsa的授权验证机器码 4 1.5. ...
- Java实现SSH模式加密原理及代码
一.SSH加密原理 SSH是先通过非对称加密告诉服务端一个对称加密口令,然后进行验证用户名和密码的时候,使用双方已经知道的加密口令进行加密和解密,见下图: 解释:SSH中为什么要使用非对称加密,又使用 ...
- HTTPS加密原理与过程
HTTPS加密原理与过程 HTTP 超文本传输协议一种属于应用层的协议 缺点: 通信使用明文(不加密),内容可能会被窃听 不验证通信方的身份,因此有可能遭遇伪装 无法证明报文的完整性,所以有可能已遭篡 ...
- 密码学——网间数据加密传输全流程(SSL加密原理)
0.导言 昨天写了一篇关于<秘钥与公钥>的文章,写的比较简单好理解,有点儿像过家家,如果详细探究起来会有不少出入,今天就来详细的说明一下数据加密的原理和过程.这个原理就是大名鼎鼎SSL的加 ...
- 一篇读懂HTTPS:加密原理、安全逻辑、数字证书等
1.引言 HTTPS(全称: Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.本文,就来深入介绍下其 ...
- AES加密解密 助手类 CBC加密模式
"; string result1 = AESHelper.AesEncrypt(str); string result2 = AESHelper.AesDecrypt(result1); ...
- SHA-256 加密原理
网络中传输敏感信息的时候通常会对字符串做加密解密处理 SHA-256 加密原理
- HTTPS加密原理(转)
Header HTTP.HTTPS在我们日常开发中是经常会接触到的. 我们也都知道,一般 Android 应用开发,在请求 API 网络接口的时候,很多使用的都是 HTTP 协议:使用浏览器打开网页, ...
随机推荐
- Jmeter_Http默认请求值
1.线程组->配置原件->Http请求默认值 2.作用:几个Http 请求参数都是重复的数据 3.优先级:Http请求默认值和单个Http请求数值,使用单个Http请求数值为主 举例如下: ...
- 中国社交电商最新展望,S-KOL-C正突围而出
编辑 | 韩星 出品 | 于见(mpyujian) 通信技术.移动互联网的快速发展正加速国内电商平台的深度变革. 在这场以"社交"和"下沉市场"为关键词的电商之 ...
- 人物 - 安迪·葛洛夫,Andrew Stephen Grove,Andy Grove
安德鲁·史蒂芬·格罗夫英语:Andrew Stephen Grove,昵称安迪·格罗夫(Andy Grove) 1. 前Intel的CEO 2. 1985 年将英特尔带入计算机处理器市场,帮助Inte ...
- Activiti工作流学习笔记一
Activiti工作流 一:Activiti第一天 1:工作流的概念 说明: 假设:这两张图就是华谊兄弟的请假流程图 图的组成部分: 人物:范冰冰冯小刚王中军 事件(动作):请假.批准.不批准 工作流 ...
- mapreduce程序执行过程
1.客户端程序,设置作业相关的配置和计算输入分片信息,向RM获取一个JOBID,提交作业信息(分片)到以作业ID为目录下,通知APP——MASTER 2.APP——MASTER,读取指定目录下的作业信 ...
- 二十 Struts2的标签库,数据回显(基于值栈)
通用标签库 判断标签:<s:if>.<s:elseif>.<s:else> 循环标签:<s:iterator> 其他常用标签: <s:proper ...
- git 删除分支和回退到以前某个提交版本
1.git 创建和删除分支: 创建:git branch 分支名字 本地删除:git branch -D 分支名字 远程删除:git push origin :分支名字 2.git 回退到以前提交的版 ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表格:在 <tbody> 内的任一行启用鼠标悬停状态
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 实用类-<字符串与基本类型的转换>
字符串与基本类型的转换 字符串->基本类型 int i5=Integer.parseInt("123"); System.out.println(i5); 基本类型-> ...
- android下创建文件夹和修改其权限的方法
原文:http://www.cnblogs.com/wanqieddy/archive/2011/12/28/2304906.html 由于工作的需要,今天研究了在android下创建文件夹和修改其权 ...