Java安全學習筆記(三)--CBC方式加密
阿新 • • 發佈:2019-01-31
CBC使用一個8個位元組的隨機數(稱為初始向量,IV)來加密第一個分組,然後使用得到的密文加密第二個分組,加密第二個分組得到的密文再加密第三個分組,....這樣,即使兩個分組相同,得到的密文也是不同的。本例項演示使用CBC加密方式以及初始化向量進行加密,並匯入到EncCBC.dat檔案中。
使用CBC方式對字串進行加密的技術要點如下:
從key1.dat檔案中獲取金鑰
利用8位元組隨機數陣列rand(IV)來初始化IvParameterSpec物件
獲取密碼器Cipher,並初始化
把明文S轉化成位元組陣列ptext[]
把ptext[]進行CBC加密
把結果輸出到EncCBC.dat檔案中。
源程式解讀: (1)首先要從key1.dat檔案中獲取金鑰,key1.dat的生成是通過程式Java安全學習筆記(二)--建立對稱金鑰 來生成的金鑰key的。 (2)使用CBC方式首先要生成初始向量,然後再獲取密碼器物件時,通過getInstance()方法指定加密方式,該引數DESede/CBC/PKCS5Padding由3個引數組成。其中第一個引數DESede代表所有的加密演算法,第2個引數CBC即加密模式,除CBC外,還有NONE,ECB,CFB,OFB和PCBC等可以用;第三個引數為填充模式,對稱加密常用的填充方式成為PKCS5Padding,如果加密演算法不進行填充,則填充方式為NoPadding。 (3)呼叫doFinal()方法執行加密演算法 (4)EncCBC.dat資料分為兩部分:8位元組隨機陣列rand+加密後密文位元組陣列ctext,其中儲存8位元組隨機陣列rand的目的是為了解密演算法可以構建跟加密演算法一樣的IvParameterSpec物件。
package core; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.security.Key; import java.util.Random; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; public class ENC_CBC { public static void main(String[] args) throws Exception { //獲取金鑰 String path=System.getProperty("user.dir"); //獲取程式當前路徑 path=path+"/key1.dat";//得到金鑰的路徑 //System.out.println(path); FileInputStream f1=new FileInputStream(path); //獲取金鑰 ObjectInputStream b=new ObjectInputStream(f1);//建立物件輸入流 Key k=(Key) b.readObject(); //從ObjectInputStream中讀取key物件 //生成初始化向量 IV byte[] rand=new byte[8];//生成有8個元素的位元組陣列 Random r=new Random(); r.nextBytes(rand);//把隨機生成的位元組置於rand位元組數字中,nextBytes的底層實現是for迴圈 IvParameterSpec iv=new IvParameterSpec(rand);//使用rand中的位元組作為IV來初始化一個IvParameterSpec物件 //加密 Cipher cp=Cipher.getInstance("DESede/CBC/PKCS5Padding");//獲取密碼器例項 cp.init(Cipher.ENCRYPT_MODE, k, iv);//三個引數:第一個引數表示是加密模式,第二個引數是金鑰key,第三個引數是加密演算法IvParameterSpec //明文 String s="你好Java你好Java你好Java你好Java"; byte ptext[]=s.getBytes("UTF8");//按UTF8編碼把明文轉換成位元組陣列 byte ctext[]=cp.doFinal(ptext);//加密 //列印明文位元組陣列 System.out.println("輸出明文位元組陣列為: "); for (int i = 0; i < ptext.length; i++) { System.out.print(ptext[i]+","); if((i+1)%5==0) System.out.println(); } //列印加密結果 System.out.println("輸出加密結果為: "); for (int i = 0; i < ctext.length; i++) { System.out.print(ctext[i]+","); if((i+1)%5==0) System.out.println(); } //儲存加密結果 FileOutputStream f2=new FileOutputStream("EncCBC.dat"); f2.write(rand);//把隨機數陣列寫入,供後續解密演算法獲取 f2.write(ctext);//密文位元組陣列 f2.close();//關閉輸出流 } }
源程式解讀: (1)首先要從key1.dat檔案中獲取金鑰,key1.dat的生成是通過程式Java安全學習筆記(二)--建立對稱金鑰 來生成的金鑰key的。 (2)使用CBC方式首先要生成初始向量,然後再獲取密碼器物件時,通過getInstance()方法指定加密方式,該引數DESede/CBC/PKCS5Padding由3個引數組成。其中第一個引數DESede代表所有的加密演算法,第2個引數CBC即加密模式,除CBC外,還有NONE,ECB,CFB,OFB和PCBC等可以用;第三個引數為填充模式,對稱加密常用的填充方式成為PKCS5Padding,如果加密演算法不進行填充,則填充方式為NoPadding。 (3)呼叫doFinal()方法執行加密演算法 (4)EncCBC.dat資料分為兩部分:8位元組隨機陣列rand+加密後密文位元組陣列ctext,其中儲存8位元組隨機陣列rand的目的是為了解密演算法可以構建跟加密演算法一樣的IvParameterSpec物件。