<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一文搞懂對稱加密:加密算法、工作模式、填充方式、代碼實現(xiàn)

          共 5979字,需瀏覽 12分鐘

           ·

          2021-11-04 02:22

          微信搜索:碼農(nóng)StayUp

          主頁地址:https://gozhuyinglong.github.io

          享:https://github.com/gozhuyinglong/blog-demos

          上篇介紹了《單向散列加密》,它是一種消息摘要算法。該算法在信息安全領(lǐng)域,有很多重要的應(yīng)用場景,比如:用戶密碼保護(hù)、數(shù)字簽名、文件完整性校驗、云盤妙傳等。

          單向散列加密只能夠?qū)ο⑦M(jìn)行加密(嚴(yán)格來說是計算消息的摘要),想要實現(xiàn)對密文解密,需要使用其它加密方式了。今天介紹一個在信息安全領(lǐng)域中,比較重要的加密方式——對稱加密。

          下面是本篇講述內(nèi)容:

          加密、解密和密鑰

          加密(Encrypt)是從明文生成密文的步驟,解密(Decrypt)是從密文還原成明文的步驟,而這兩個步驟都需要用到密鑰(Key)。這和我們現(xiàn)實中,用鑰匙上鎖和開鎖是一樣的。

          加密、解密和密鑰

          什么是對稱加密

          對稱加密(Symmetric Cryptography)是密碼學(xué)中的一類加密算法,這類算法在加密和解密時,使用相同的密鑰。

          對稱加密又稱為共享密鑰加密,其最大的缺點是,對稱加密的安全性依賴于密鑰,一旦泄露,就意味著任何人都能解密消息。

          對稱加密的優(yōu)點是加密速度快,所以在很多場合被使用。

          常見算法

          本節(jié)介紹對稱加密的一些常見算法,包括DES、3DES和AES。

          DES算法

          DES(Data Encryption Standard,中文:數(shù)據(jù)加密標(biāo)準(zhǔn)),是一種對稱加密算法。該算法在1976年被美國聯(lián)邦政府的國家標(biāo)準(zhǔn)局確定為聯(lián)邦資料處理標(biāo)準(zhǔn)(FIPS),并于1977年被發(fā)布,隨后在國際上廣泛流傳開來。然而,隨著計算機(jī)的進(jìn)步,DES 已經(jīng)能夠被暴力破解,所以該算法已經(jīng)不安全了。

          DES是一種分組密碼(Block Cipher,或者叫塊加密),即將明文按64比特進(jìn)行分組加密,每組生成64位比特的密文。它的密鑰長度為56比特(從規(guī)格上來說,密鑰長度是64比特,但由于每隔7比特會設(shè)置一個用于錯誤檢查的比特,因此實際長度為56比特)。

          DES算法

          3DES算法

          三重數(shù)據(jù)加密算法(Triple Data Encryption Algorithm,縮寫為TDEA),簡稱3DES(Triple-DES),是DES的增強(qiáng)版,相當(dāng)于對每組數(shù)據(jù)應(yīng)用了三次DES算法。

          由于DES算法的密鑰長度過短,容易被暴力破解,為了解決這一問題,設(shè)計出了該算法。它使用簡單的方法,通過增加DES密鑰長度的方式來避免類似攻擊,而不是一種全新的密碼算法。

          該算法在每次應(yīng)用DES時,使用不同的密鑰,所以有三把獨立密鑰。這三把密鑰組成一起,是一個長度為168(56 + 56 + 56)比特的密鑰,所以3DES算法的密鑰總長度為168比特。

          3DES的加密過程,并不是進(jìn)行三次DES加密(加密→加密→加密),而是以密鑰1、密鑰2、密鑰3的順序,進(jìn)行加密解密加密的過程。

          3DES加密

          3DES的解密過程和加密正好相反,是以密鑰3、密鑰2、密鑰1的順序,進(jìn)行解密加密解密的操作。

          3DES解密

          AES算法

          AES(Advanced Encryption Standard),即高級加密標(biāo)準(zhǔn),是取代DES算法的一種新的對稱加密算法。AES算法是從全世界的企業(yè)和密碼學(xué)家,提交的對稱密碼算法中競選出來的,最終 Rijndael 加密算法勝出,所以AES又稱為 Rijndael 加密算法。

          AES也是一種分組密碼,它的分組長度為128比特,密鑰長度可以為128比特、192比特或256比特。

          AES算法

          分組密碼的模式

          上面介紹的DES、3DES和AES都屬于分組密碼,它們只能加密固定長度的明文。如果需要加密更長的明文,就需要對分組密碼進(jìn)行迭代,而分組密碼的迭代方法稱為分組密碼的模式(Model)。簡而一句話:分組密碼的模式,就是分組密碼的迭代方式。

          分組密碼有很多種模式,這里主要介紹以下幾種:ECB、CBC、CFB、OFB、CTR。

          明文分組與密文分組

          在下面對模式的介紹時,會用到兩個術(shù)語,這里先介紹一下:

          在分組密碼中,我們稱每組的明文為明文分組,每組生成的密文稱為密文分組。

          若將所有的明文分組合并起來就是完整的明文(先忽略填充),將所以的密文分組合并起來就是完整的密文。

          ECB模式

          ECB(Electronic CodeBook)模式,即電子密碼本模式。該模式是將明文分組,加密后直接成為密文分組,分組之間沒有關(guān)系。

          ECB模式

          ECB模式是所有模式中最簡單的一種,該模式的明文分組與密文分組是一一對應(yīng)的關(guān)系,若明文分組相同,其密文分組也一定相同。因此,ECB模式也是最不安全的模式。

          CBC模式

          CBC(Cipher Block Chaining)模式,即密碼分組鏈接模式。該模式首先將明文分組與前一個密文分組進(jìn)行XOR運(yùn)算,然后再進(jìn)行加密。只有第一個明文分組特殊,需要提前為其生成一個與分組長度相同的比特序列,進(jìn)行XOR運(yùn)算,這個比特序列稱為初始化向量(Initialization Vector),簡稱IV。

          CBC模式

          CFB模式

          CFB(Cipher FeedBack)模式,即密文反饋模式。該模式首先將前一個密文分組進(jìn)行加密,再與當(dāng)前明文分組進(jìn)行XOR運(yùn)算,來生成密文分組。同樣CFB模式也需要一個IV。

          CFB模式

          OFB模式

          OFB(Output FeedBack)模式,即輸出反饋模式。該模式會產(chǎn)生一個密鑰流,即將密碼算法的前一個輸出值,做為當(dāng)前密碼算法的輸入值。該輸入值再與明文分組進(jìn)行XOR運(yùn)行,計算得出密文分組。該模式需要一個IV,進(jìn)行加密后做為第一個分組的輸入。

          OFB模式

          CTR模式

          CTR(CounTeR)模式,即計數(shù)器模式。該模式也會產(chǎn)生一個密鑰流,它通過遞增一個計數(shù)器來產(chǎn)生連續(xù)的密鑰流。對該計數(shù)器進(jìn)行加密,再與明文分組進(jìn)行XOR運(yùn)算,計算得出密文分組。

          CTR模式

          分組密碼的填充

          在分組密碼中,當(dāng)數(shù)據(jù)長度不符合分組長度時,需要按一定的方式,將尾部明文分組進(jìn)行填充,這種將尾部分組數(shù)據(jù)填滿的方法稱為填充(Padding)。

          No Padding

          即不填充,要求明文的長度,必須是加密算法分組長度的整數(shù)倍。

          ...?|?DD?DD?DD?DD?DD?DD?DD?DD?|?DD?DD?DD?DD?DD?DD?DD?DD?|

          ANSI X9.23

          在填充字節(jié)序列中,最后一個字節(jié)填充為需要填充的字節(jié)長度,其余字節(jié)填充0。

          ...?|?DD?DD?DD?DD?DD?DD?DD?DD?|?DD?DD?DD?DD?00?00?00?04?|

          ISO 10126

          在填充字節(jié)序列中,最后一個字節(jié)填充為需要填充的字節(jié)長度,其余字節(jié)填充隨機(jī)數(shù)。

          ...?|?DD?DD?DD?DD?DD?DD?DD?DD?|?DD?DD?DD?DD?81?A6?23?04?|

          PKCS#5和PKCS#7

          在填充字節(jié)序列中,每個字節(jié)填充為需要填充的字節(jié)長度。

          ...?|?DD?DD?DD?DD?DD?DD?DD?DD?|?DD?DD?DD?DD?04?04?04?04?|

          ISO/IEC 7816-4

          在填充字節(jié)序列中,第一個字節(jié)填充固定值80,其余字節(jié)填充0。若只需填充一個字節(jié),則直接填充80

          ...?|?DD?DD?DD?DD?DD?DD?DD?DD?|?DD?DD?DD?DD?80?00?00?00?|

          ...?|?DD?DD?DD?DD?DD?DD?DD?DD?|?DD?DD?DD?DD?DD?DD?DD?80?|

          Zero Padding

          在填充字節(jié)序列中,每個字節(jié)填充為0。

          ...?|?DD?DD?DD?DD?DD?DD?DD?DD?|?DD?DD?DD?DD?00?00?00?00?|

          Java代碼實現(xiàn)

          Java在底層已經(jīng)封裝好了對稱加密的實現(xiàn), 我們只需要使用即可?,F(xiàn)在介紹幾個重要的類:

          SecureRandom類

          SecureRandom類是一個強(qiáng)安全的隨機(jī)數(shù)生成器(Random Number Generator,簡稱:RNG),加密相關(guān)的推薦使用此隨機(jī)數(shù)生成器。

          我們可以通過構(gòu)造方法生成一個實例,或者向構(gòu)造方法傳遞一個種子來創(chuàng)建實例。

          SecureRandom?random?=?new?SecureRandom();

          KeyGenerator類

          KeyGenerator類是對稱密碼的密鑰生成器,需要指定加密算法,來生成相應(yīng)的密鑰。

          Java中支持的算法:

          • AES (128)
          • DES (56)
          • DESede (168)
          • HmacSHA1
          • HmacSHA256

          下面是一些標(biāo)準(zhǔn)算法的介紹:

          標(biāo)準(zhǔn)算法

          生成密鑰代碼如下:

          /**
          ?*?通過密碼和算法獲取?Key?對象
          ?*
          ?*?@param?key???????密鑰
          ?*?@param algorithm 算法,例如:AES (128)、DES (56)、DESede (168)、HmacSHA1、HmacSHA256
          ?*?@return?密鑰?Key
          ?*?@throws?Exception
          ?*/
          private?static?Key?getKey(byte[]?key,?String?algorithm)?throws?Exception?{
          ????//?通過算法獲取?KeyGenerator?對象
          ????KeyGenerator?keyGenerator?=?KeyGenerator.getInstance(algorithm);
          ????//?使用密鑰做為隨機(jī)數(shù),初始化?KeyGenerator?對象
          ????keyGenerator.init(new?SecureRandom(key));
          ????//?生成?Key
          ????return?keyGenerator.generateKey();
          }

          Cipher類

          Cipher類提供了加密和解密的功能。該類需要指定一個轉(zhuǎn)換(Transformation)來創(chuàng)建一個實例,轉(zhuǎn)換的命名方式:算法名稱/工作模式/填充方式。

          下面是Java支持的轉(zhuǎn)換:

          • AES/CBC/NoPadding (128)
          • AES/CBC/PKCS5Padding (128)
          • AES/ECB/NoPadding (128)
          • AES/ECB/PKCS5Padding (128)
          • DES/CBC/NoPadding (56)
          • DES/CBC/PKCS5Padding (56)
          • DES/ECB/NoPadding (56)
          • DES/ECB/PKCS5Padding (56)
          • DESede/CBC/NoPadding (168)
          • DESede/CBC/PKCS5Padding (168)
          • DESede/ECB/NoPadding (168)
          • DESede/ECB/PKCS5Padding (168)
          • RSA/ECB/PKCS1Padding (1024, 2048)
          • RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
          • RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)

          下面是一些標(biāo)準(zhǔn)的模式:

          標(biāo)準(zhǔn)模式

          下面是一些標(biāo)準(zhǔn)的填充:

          標(biāo)準(zhǔn)填充

          加密代碼如下:

          private?static?final?String?DES_ALGORITHM?=?"DES";
          private?static?final?String?DES_TRANSFORMATION?=?"DES/ECB/PKCS5Padding";

          /**
          ?*?DES?加密
          ?*
          ?*?@param?data?原始數(shù)據(jù)
          ?*?@param?key??密鑰
          ?*?@return?密文
          ?*/
          private?static?byte[]?encryptDES(byte[]?data,?byte[]?key)?throws?Exception?{
          ????//?獲取?DES?Key
          ????Key?secretKey?=?getKey(key,?DES_ALGORITHM);

          ????//?通過標(biāo)準(zhǔn)轉(zhuǎn)換獲取?Cipher?對象,?由該對象完成實際的加密操作
          ????Cipher?cipher?=?Cipher.getInstance(DES_TRANSFORMATION);
          ????//?通過加密模式、密鑰,初始化?Cipher?對象
          ????cipher.init(Cipher.ENCRYPT_MODE,?secretKey);
          ????//?生成密文
          ????return?cipher.doFinal(data);
          }

          解密代碼如下:

          private?static?final?String?DES_ALGORITHM?=?"DES";
          private?static?final?String?DES_TRANSFORMATION?=?"DES/ECB/PKCS5Padding";

          /**
          ?*?DES?解密
          ?*
          ?*?@param?data?密文
          ?*?@param?key??密鑰
          ?*?@return?原始數(shù)據(jù)
          ?*/
          private?static?byte[]?decryptDES(byte[]?data,?byte[]?key)?throws?Exception?{
          ????//?獲取?DES?Key
          ????Key?secretKey?=?getKey(key,?DES_ALGORITHM);
          ????//?通過標(biāo)準(zhǔn)轉(zhuǎn)換獲取?Cipher?對象,?由該對象完成實際的加密操作
          ????Cipher?cipher?=?Cipher.getInstance(DES_TRANSFORMATION);
          ????//?通過解密模式、密鑰,初始化?Cipher?對象
          ????cipher.init(Cipher.DECRYPT_MODE,?secretKey);
          ????//?生成原始數(shù)據(jù)
          ????return?cipher.doFinal(data);
          }

          完整代碼

          完整代碼請訪問我的Github,若對你有幫助,歡迎給個?,感謝~~??????

          https://github.com/gozhuyinglong/blog-demos/blob/main/java-source-analysis/src/main/java/io/github/gozhuyinglong/utils/SymmetricKeyUtil.java

          推薦閱讀

          掃碼關(guān)注,不迷路


          瀏覽 70
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  夏夏粉嫩黑鲍鱼大胆尤物P | 天美张佳晨 | 无码人妻精品一区二区在线 | 欧美三级台湾三级少妇 | 欧美色哟哟哟 |