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();//关闭输出流
}
}
源程序解读:
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对象。