加密模式和填充模式
加密模式
加密模式:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html
ECB
ECB : Electronic codebook, 電子密碼本. 需要加密的消息按照塊密碼的塊大小被分為數個塊,并對每個塊進行獨立加密
- 優點 : 可以并行處理數據
- 缺點 : 同樣的原文生成同樣的密文, 不能很好的保護數據
- 同時加密,原文是一樣的,加密出來的密文也是一樣的
CBC
CBC : Cipher-block chaining, 密碼塊鏈接. 每個明文塊先與前一個密文塊進行異或后,再進行加密。在這種方法中,每個密文塊都依賴于它前面的所有明文塊
- 優點 : 同樣的原文生成的密文不一樣
- 缺點 : 串行處理數據.
填充模式
- 當需要按塊處理的數據, 數據長度不符合塊處理需求時, 按照一定的方法填充滿塊長的規則
NoPadding
- 不填充.
- 在DES加密算法下, 要求原文長度必須是8byte的整數倍
- 在AES加密算法下, 要求原文長度必須是16byte的整數倍
PKCS5Padding
數據塊的大小為8位, 不夠就補足
Tips
- 默認情況下, 加密模式和填充模式為 : ECB/PKCS5Padding
- 如果使用CBC模式, 在初始化Cipher對象時, 需要增加參數, 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());
加密模式和填充模式
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)加密模式和填充模式例子
package com.leon.desaes;import com.sun.org.apache.xml.internal.security.utils.Base64;import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec;public class DesDemo {// DES加密算法,key的大小必須是8個字節public static void main(String[] args) throws Exception {String input ="硅谷";// DES加密算法,key的大小必須是8個字節String key = "12345678";// 指定獲取Cipher的算法,如果沒有指定加密模式和填充模式,ECB/PKCS5Padding就是默認值// String transformation = "DES"; // 9PQXVUIhaaQ=//String transformation = "DES/ECB/PKCS5Padding"; // 9PQXVUIhaaQ=// CBC模式,必須指定初始向量,初始向量中密鑰的長度必須是8個字節//String transformation = "DES/CBC/PKCS5Padding"; // 9PQXVUIhaaQ=// NoPadding模式,原文的長度必須是8個字節的整倍數 ,所以必須把 硅谷改成硅谷12String transformation = "DES/CBC/NoPadding"; // 9PQXVUIhaaQ=// 指定獲取密鑰的算法String algorithm = "DES";String encryptDES = encryptDES(input, key, transformation, algorithm);System.out.println("加密:" + encryptDES); // String s = dncryptDES(encryptDES, key, transformation, algorithm); // System.out.println("解密:" + s);}/*** 使用DES加密數據** @param input : 原文* @param key : 密鑰(DES,密鑰的長度必須是8個字節)* @param transformation : 獲取Cipher對象的算法* @param algorithm : 獲取密鑰的算法* @return : 密文* @throws Exception*/private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {// 獲取加密對象Cipher cipher = Cipher.getInstance(transformation);// 創建加密規則// 第一個參數key的字節// 第二個參數表示加密算法SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);// ENCRYPT_MODE:加密模式// DECRYPT_MODE: 解密模式// 初始向量,參數表示跟誰進行異或,初始向量的長度必須是8位 // IvParameterSpec iv = new IvParameterSpec(key.getBytes());// 初始化加密模式和算法cipher.init(Cipher.ENCRYPT_MODE,sks);// 加密byte[] bytes = cipher.doFinal(input.getBytes());// 輸出加密后的數據String encode = Base64.encode(bytes);return encode;}/*** 使用DES解密** @param input : 密文* @param key : 密鑰* @param transformation : 獲取Cipher對象的算法* @param algorithm : 獲取密鑰的算法* @throws Exception* @return: 原文*/private static String dncryptDES(String input, String key, String transformation, String algorithm) throws Exception {// 1,獲取Cipher對象Cipher cipher = Cipher.getInstance(transformation);// 指定密鑰規則SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // IvParameterSpec iv = new IvParameterSpec(key.getBytes());cipher.init(Cipher.DECRYPT_MODE, sks);// 3. 解密byte[] bytes = cipher.doFinal(Base64.decode(input));return new String(bytes);} }修改成?CBC?加密 模式
String transformation = "DES/CBC/PKCS5Padding";運行 ,報錯,需要添加一個參數
修改加密代碼:
修改填充模式
String transformation = "DES/CBC/NoPadding";運行報錯?NoPadding?這種填充模式 原文必須是8個字節的整倍數
修改運行
在測試?AES?的時候需要注意,key需要16個字節,加密向量也需要16個字節 ,其他方式跟?DES?一樣
?
總結