Docker-compose是什麼?能幹嘛?解決了哪些痛點? 是什麼? Docker-compose是Docker官方推出 的一個工具軟體,可以管理多個Docker容器組成的一個應用。你需要編寫一個一個YAML格式的配置文件:docker-compose.yml。寫好多個容器之間的調用關係。然後,只 ...
一、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 = "待加密的數據"; 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>