1. 程式人生 > >Java安全學習筆記(三)--CBC方式加密

Java安全學習筆記(三)--CBC方式加密

CBC使用一個8個位元組的隨機數(稱為初始向量,IV)來加密第一個分組,然後使用得到的密文加密第二個分組,加密第二個分組得到的密文再加密第三個分組,....這樣,即使兩個分組相同,得到的密文也是不同的。本例項演示使用CBC加密方式以及初始化向量進行加密,並匯入到EncCBC.dat檔案中。 使用CBC方式對字串進行加密的技術要點如下: 從key1.dat檔案中獲取金鑰 利用8位元組隨機數陣列rand(IV)來初始化IvParameterSpec物件 獲取密碼器Cipher,並初始化 把明文S轉化成位元組陣列ptext[] 把ptext[]進行CBC加密 把結果輸出到EncCBC.dat檔案中。
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物件。