一、DES簡介
DES是一種對稱加密(Data Encryption Standard)演算法,于1977年得到美國政府的正式許可,是一種用56位密鑰來加密64位資料的方法,一般密碼長度
為8個位元組,其中56位加密密鑰,每個第8位都用作奇偶校驗,
DES演算法一般有兩個關鍵點,第一個是加密演算法,第二個是資料補位,
二、加密演算法型別
1、電子密文方式(ECB)
ECB模式是分組密碼的基本作業方式,在該模式下,每個加密區塊按順序進行獨立加密,得到獨立的密文區塊,每個加密區塊的結果都不會被其
他區塊影響,用此方式,可用平行處理實施加速加、解密運算,且在網路傳輸時任何一一個區塊出現錯誤,也不存在影響到其他區塊傳輸的結果,這是
該模式的好處,
ECB模式的不足是易使明文的資料模式暴露,在計算機系統里,很多資料均存在固有模式,這主要是由資料結構與資料冗余導致的,若無任何措
施,針對在需加密的檔案里出現多回的明文,這部分明文如果剛好是加密區塊的大小,則可能會得到一樣的密文,且密文內容如果受到剪貼、代替
也很難被發現,
2、密文分組鏈接方式(CBC)
第一個加密區塊先與初始向量做異或運算,再進行加密,其他每個加密區塊在加密之前,必須與前一個加密區塊的密文做一次異或運算,再進行
加密,每個區塊的加密結果都會被前面全部區塊內容的影響,因此盡管在明文里出現多次一樣的明文,也會得到不一樣的密文,
還有,密文內容如果遇到剪貼、替換,或于網路傳輸時出現錯誤,則它后面的密文會被破壞,不能順利解密還原,這是這一模式的優點也是缺點,
其次,一定得選取1個初始向量來加密第1個區塊,且加密作業時不能用平行處理加速加密運算,不過解密運算,做異或的加密區塊結果已經有了,
則還可用平行處理加速,
3、密文反饋方式(CFB)
可把區塊加密演算法作流密碼加密器用,流密碼加密器可由實際需要,每回加密區塊的大小能自行確定每個區塊的明文與之前區塊加密后的密文
異或后,變成密文,因此, 每一一個區塊的加密結果也受之前所有區塊內容的影響,也會使在明文中出現多回一樣的明文都得到不一樣的密文,在
這個模式下,和CBC模式相同,為了加密第1個區塊,一定得選1個初始向量,且其必須只有一個、每次加密時肯定不一樣,也很難用平行處理加快
加密作業,
4、輸出反饋模式(OFB)
OFB與CFB大致相同,唯一的差 異是每個區塊的明文與之前區塊加密后的密文做異或后產生密文,之前區塊加密后的密文是獨立產生的,每個
區塊的加密結果不會被前面全部區塊內容影響,若存在區塊在傳輸中丟失或出現錯誤,不至于不能完全解密,但也會使在明文中出現多回的明文,
都得到同樣的密文,也易遭遇剪接攻擊,而在此模式下,為了加密第1個區塊,一定得 設定1個初始向量,要不然很難用平行處理加快加密作業,
容易看出,以上4種操作模式有不同的優點和缺點,在ECB與OFB中改變- -個明文塊會使有關的密文塊發生改變,但其他密文塊不變,有些情況
下這可能是-一個好的特性,另-方面,在CBC與CFB中改變一個明文塊,那么對應的密文塊及它后面的全部密文塊會改變,此特性代表CBC與
CFB模式適合于鑒別,更明確地說,這些模式能用來產生訊息鑒別碼,將其附在明文塊序列的后面可保護訊息的完整性,
二、資料補位
1、NoPadding
API或演算法本身不對資料進行處理,加密資料由加密雙方約定填補演算法,例如若對字串資料進行加解密,可以補充\0或者空格,然后trim
2、PKCS5Padding
加密前:資料位元組長度對8取余,余數為m,若m>0,則補足8-m個位元組,位元組數值為8-m,即差幾個位元組就補幾個位元組,位元組數值即為補充的位元組數,若為0則補充8個位元組的8
解密后:取最后一個位元組,值為m,則從資料尾部洗掉m個位元組,剩余資料即為加密前的原文
因為DES是一種block cipher,一個block要8個位元組,所以要加密的東西要分成8位元組的整數倍,不足的就填充,
PKCS5Padding這種填充,填的位元組代表所填位元組的總數:
比如差三個位元組的話填為 @@@@@333 差7個位元組就填為 @7777777 沒有差就填 88888888
三、代碼示例
package com.js.port.rainy.commons.util; import org.apache.tomcat.util.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.security.Key; import java.security.Security; public class DESUtils { private static final String src = "https://www.cnblogs.com/yunsun/archive/2022/12/30/待加密的資料"; public static void main(String[] args) { System.out.println("des jdk加密模式"); jdkDES(); System.out.println("-------------------------"); System.out.println("des bc加密模式"); bcDES(); } /** * jdk加密模式(des) * */ public static void jdkDES() { try { //生成KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); keyGenerator.getProvider(); keyGenerator.init(56); SecretKey secretKey = keyGenerator.generateKey(); byte[] bytesKey = secretKey.getEncoded(); //key轉換 DESKeySpec desKeySpec = new DESKeySpec(bytesKey); SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); Key convertSecretKey = factory.generateSecret(desKeySpec); //加密 加密方式/作業模式/填充方式 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //方式/秘鑰 cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdk des加密后的資料:"+ Base64.encodeBase64String(result)); //解密 方式/秘鑰 cipher.init(Cipher.DECRYPT_MODE,convertSecretKey); result = cipher.doFinal(result); System.out.println("jdk des解密后的資料:" + new String(result)); } catch (Exception e) { System.out.println("error:"+e.getMessage()); } } /** * bc加密模式(des) * */ public static void bcDES() { try { Security.addProvider(new BouncyCastleProvider()); //生成KEY KeyGenerator keyGenerator = KeyGenerator.getInstance("DES","BC"); keyGenerator.getProvider(); keyGenerator.init(56); SecretKey secretKey = keyGenerator.generateKey(); byte[] bytesKey = secretKey.getEncoded(); //key轉換 DESKeySpec desKeySpec = new DESKeySpec(bytesKey); SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); Key convertSecretKey = factory.generateSecret(desKeySpec); //加密 加密方式/作業模式/填充方式 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //方式/秘鑰 cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("bc des加密后的資料:"+ Base64.encodeBase64String(result)); //解密 方式/秘鑰 cipher.init(Cipher.DECRYPT_MODE,convertSecretKey); result = cipher.doFinal(result); System.out.println("bc des解密后的資料:" + new String(result)); } catch (Exception e) { System.out.println("error:"+e.getMessage()); } } }
輸出結果:

pom參考
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/540976.html
標籤:其他
