日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

CBC加密原理及攻击

發(fā)布時(shí)間:2024/4/24 综合教程 44 生活家
生活随笔 收集整理的這篇文章主要介紹了 CBC加密原理及攻击 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原理
基于分組加密
加密過(guò)程

Plaintext:明文,待加密的數(shù)據(jù)。
IV:用于隨機(jī)化加密的比特塊,保證即使對(duì)相同明文多次加密,也可以得到不同的密文,初始向量,用來(lái)與第一塊的明文異或運(yùn)算。
Key:被一些如AES的對(duì)稱(chēng)加密算法使用。
Ciphertext:密文,加密后的數(shù)據(jù)。
在這里重要的一點(diǎn)是,CBC工作于一個(gè)固定長(zhǎng)度的比特組,將其稱(chēng)之為塊。在本文中,我們將使用包含16字節(jié)的塊。
? Ciphertext-0 = Encrypt(Plaintext XOR IV)—只用于第一個(gè)組塊
? Ciphertext-N= Encrypt(Plaintext XOR Ciphertext-N-1)—用于第二及剩下的組塊
XOR為異或運(yùn)算 , N為第N塊數(shù)據(jù)
---------------------------------------------------------------------------
上述的公式和圖可以簡(jiǎn)單描述為:
1.將要CBC加密的數(shù)據(jù)分為N個(gè)塊,每個(gè)塊為16字節(jié)
2.隨機(jī)找一個(gè)IV(初始向量),大小為每個(gè)塊的大小(16字節(jié)),用于與第一個(gè)塊進(jìn)行異或運(yùn)算
3.將異或運(yùn)算的結(jié)果進(jìn)行選定的加密方式進(jìn)行加密
4.將得到的第一塊密文與第二塊明文進(jìn)行異或運(yùn)算
5.將異或運(yùn)算的結(jié)果進(jìn)行選定的加密方式進(jìn)行加密
6.將得到的第二塊密文與第三塊明文進(jìn)行異或運(yùn)算
7.將異或運(yùn)算的結(jié)果進(jìn)行選定的加密方式進(jìn)行加密
8.最后得到三塊加密獲得的密文
注意:正如你所見(jiàn),前一塊的密文用來(lái)產(chǎn)生后一塊的密文。
----------------------------------------------------------------------
解密過(guò)程
Decryption Process


? Plaintext-0 = Decrypt(Ciphertext) XOR IV—只用于第一個(gè)組塊
? Plaintext-N= Decrypt(Ciphertext) XOR Ciphertext-N-1—用于第二及剩下的組塊
? -----------------------------------------------------------------------------------
上述的公式和圖可以簡(jiǎn)單描述為:
1.將已經(jīng)CBC加密的數(shù)據(jù)分為N個(gè)塊,每個(gè)塊為16字節(jié)
2.將第一塊加密的數(shù)據(jù)用選定的加密方式解密
3.找到加密時(shí)的IV,用于與第一個(gè)解密后的塊進(jìn)行異或運(yùn)算,得到第一塊的明文
4.將第二塊加密數(shù)據(jù)進(jìn)行解密
5.用第一塊加密的密文與第二塊解密的塊進(jìn)行異或運(yùn)算,得到第二塊的明文
6.將第三塊加密的數(shù)據(jù)進(jìn)行解密
7.用第二塊加密的數(shù)據(jù)與第三塊解密的塊進(jìn)行異或運(yùn)算,得到第二塊的明文
通過(guò)上述的解密過(guò)程可以推算出:
如果要修改第二個(gè)塊中的第n個(gè)字節(jié)的數(shù)據(jù),只要修改第一塊數(shù)據(jù)的密文中的第n個(gè)字節(jié)數(shù)據(jù),這樣第一個(gè)塊的密文與第二個(gè)塊解密得到的數(shù)據(jù)進(jìn)行異或運(yùn)算時(shí)就可以得到自己想要的數(shù)據(jù),對(duì)第三個(gè)塊及其以后的數(shù)據(jù)都不會(huì)產(chǎn)生影響(因?yàn)榕c下一塊進(jìn)行異或運(yùn)算的都是加密的數(shù)據(jù),第二塊的加密數(shù)據(jù)沒(méi)有進(jìn)行改變),但是第一個(gè)塊修改了加密數(shù)據(jù),進(jìn)行解密和與IV異或運(yùn)算后會(huì)產(chǎn)生錯(cuò)誤數(shù)據(jù)。
以此類(lèi)推,如果要修改第三塊中的數(shù)據(jù),就修改第二塊的加密信息,會(huì)產(chǎn)生錯(cuò)誤數(shù)據(jù)的只有第二塊數(shù)據(jù),其他塊的數(shù)據(jù)不會(huì)產(chǎn)生錯(cuò)誤。
如果要修改第一塊的數(shù)據(jù)的話(huà),只能修改第一塊密文,這需要知道IV是什么,過(guò)程:
1.將第一塊的明文修改成想要的數(shù)據(jù)
2.將修改完的數(shù)據(jù)與IV進(jìn)行異或運(yùn)算,然后進(jìn)行選定方式的加密,得到密文數(shù)據(jù)
3.將第一塊的密文數(shù)據(jù)換成的到的密文數(shù)據(jù)
這樣的話(huà)會(huì)出現(xiàn)錯(cuò)誤的塊是第二塊,因?yàn)榈谝粔K的密文修改了,與第二塊的已解密的數(shù)據(jù)進(jìn)行異或運(yùn)算時(shí)產(chǎn)生錯(cuò)誤。
解決錯(cuò)誤的方式是修改IV
-----------------------------------------------------------------------------
注意:Ciphertext-N-1(密文-N-1)是用來(lái)產(chǎn)生下一塊明文;這就是字節(jié)翻轉(zhuǎn)攻擊開(kāi)始發(fā)揮作用的地方。如果我們改變Ciphertext-N-1(密文-N-1)的一個(gè)字節(jié),然后與下一個(gè)解密后的組塊異或,我們就可以得到一個(gè)不同的明文了!You got it?別擔(dān)心,下面我們將看到一個(gè)詳細(xì)的例子。與此同時(shí),下面的這張圖也可以很好地說(shuō)明這種攻擊:

0x02 一個(gè)例子(CBC Blocks of 16 bytes)

比方說(shuō),我們有這樣的明文序列:
a:2:{s:4:"name";s:6:"sdsdsd";s:8:"greeting";s:20:"echo 'Hello sdsdsd!'";}
我們的目標(biāo)是將“s:6”當(dāng)中的數(shù)字6轉(zhuǎn)換成數(shù)字“7”。我們需要做的第一件事就是把明文分成16個(gè)字節(jié)的塊:
? 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!'";}
因此,我們的目標(biāo)字符位于塊2,這意味著我們需要改變塊1的密文來(lái)改變第二塊的明文。
有一條經(jīng)驗(yàn)法則是(注:結(jié)合上面的說(shuō)明圖可以得到),你在密文中改變的字節(jié),只會(huì)影響到在下一明文當(dāng)中,具有相同偏移量的字節(jié)。所以我們目標(biāo)的偏移量是2:
? [0] = s
? [1]= :
? [2]=6
因此我們要改變?cè)诘谝粋€(gè)密文塊當(dāng)中,偏移量是2的字節(jié)。正如你在下面的代碼當(dāng)中看到的,在第2行我們得到了整個(gè)數(shù)據(jù)的密文,然后在第3行中,我們改變塊1中偏移量為2的字節(jié),最后我們?cè)僬{(diào)用解密函數(shù)。
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);
運(yùn)行這段代碼后,我們可以將數(shù)字6變?yōu)?:

但是我們?cè)诘?行中,是如何改變字節(jié)成為我們想要的值呢?
基于上述的解密過(guò)程,我們知道有,A = Decrypt(Ciphertext)與B = Ciphertext-N-1異或后最終得到C = 6。等價(jià)于:
C = A XOR B
所以,我們唯一不知道的值就是A(注:對(duì)于B,C來(lái)說(shuō))(block cipher decryption);借由XOR,我們可以很輕易地得到A的值:
A = B XOR C
最后,A XOR B XOR C等于0。有了這個(gè)公式,我們可以在XOR運(yùn)算的末尾處設(shè)置我們自己的值,就像這樣:
A XOR B XOR C XOR "7"會(huì)在塊2的明文當(dāng)中,偏移量為2的字節(jié)處得到7
--------------------------------------------------------------------
異或計(jì)算的公式:
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

目前自己測(cè)試只能修改第二塊和第一塊數(shù)據(jù)
源碼:
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();
}

輸入用戶(hù)名admir密碼1,抓取數(shù)據(jù)內(nèi)容為:
Cookie:
PHPSESSID=iq1lrnq2fhp235ndd4ke2njl73;
iv=XyP2qyLI00SzmCP8t766mA%3d%3d;
cipher=8Rhxwqez6NPucPx4mKM4oytL0QCEM6YnRhjkPTjIVvDMp8HAF2%2f8JjiWG8oSLqwgdGs4EV018W7SU63K3bYV9w%3d%3d

過(guò)程: XOR異或 、CRYPT加密(未知密鑰)、en-加密后
plain XOR iv ->after_plain CRYPT ->en-after_plain

補(bǔ)充:AES加密后的數(shù)據(jù)為16字節(jié)的整數(shù)倍,可直接進(jìn)行異或運(yùn)算

解題過(guò)程:
<?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. 因?yàn)樾蛄谢膬?nèi)容為
a:2:{s:8:"userna
me";s:5:"admik";
s:8:"password";s
:1:"1";}
所以修改塊二上的第13位數(shù)據(jù)(從0開(kāi)始),因此修改塊一13位數(shù)據(jù)(AES加密)
3. 修改數(shù)據(jù)計(jì)算:


1.算法
ciphertext XOR plaintext = 加密前xor后的plain
加密前xor后的plain XOR plaintext =ciphertext
所以比如要修改enc[23]處的值時(shí),使用的算法為enc[7]^"替換前"^"替換后"
注意錯(cuò)誤:不能使用加密后直接異或,從過(guò)程來(lái)看就為錯(cuò)誤
例如enc[23]^"H"就是錯(cuò)誤的,因?yàn)榧用芎笤井惢蚝笪恢玫淖址淖?br /> 2.關(guān)于改變后iv的獲得
由于數(shù)據(jù)改變導(dǎo)致第一塊數(shù)據(jù)異或時(shí)得到不能序列化的數(shù)據(jù),所以需要根據(jù)網(wǎng)頁(yè)返回的不能序列化的數(shù)據(jù)(也就是除iv修改完后塊一的數(shù)據(jù),base64解碼后就是序列化數(shù)據(jù))進(jìn)行異或運(yùn)算來(lái)的得到新的iv
與前面的1 運(yùn)算相同
iv XOR 網(wǎng)頁(yè)返回的數(shù)據(jù) = 加密前xor后的plain(序列化錯(cuò)誤的)
加密前xor后的plain XOR plain(正常序列的) = new_iv
所以得到iv算法為 iv ^ wrong_plain ^ plain
補(bǔ)充:由于加密解密得關(guān)系 所以不只是特定位置的字符錯(cuò)誤,需要全部異或計(jì)算

總結(jié)

以上是生活随笔為你收集整理的CBC加密原理及攻击的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。