Java安全学习笔记(三)--CBC方式加密

来源:互联网 发布:域名贴吧 编辑:程序博客网 时间:2024/05/29 17:05
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对象//生成初始化向量 IVbyte[] 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对象。