JAVA——CBC方式的解密与加密

CBC方式的解密与加密


一、创建对称密钥

现代密码算法的过程非常复杂,加密和解密使用相同的密钥,称为对称密钥算法。Java中已经提供了常用的加密算法,我们不需要了解算法的细节就可以直接使用这些算法实现加密。每一种算法所用的密钥都有所不同,本实例演示如何运用Java中提供的方法创建对称密钥,并通过对象序列化方式保存在文件中。

1.原理

首先获取密钥生成器,然后密钥的生成,最后对密钥进行保存。

2.语法

  • Java的 Keygeneratori类中提供了创建对称密钥的方法。KeyGenerator类预定义了一个静态方法 getlnstanceo,通过它获得KeyGenerator类型的对象。DES是目前最常用的对称加密算法,但安全性较差。在本程序中用于获取密钥生成器的代码如下所示:
    KeyGenerator kg =KeyGenerator.getInstance(“DESede”) //获取密钥生成器

  • 初始化密钥生成器一般是指定密钥的长度。如果不进行初始化,系统会根据算法自动使用默认的密钥长度。在本程序中用于初始化密钥生成器的代码如下所示:
    Kg.init(168); //初始化密钥生成器

  • 通过 KeyGenerator类型的对象中 generateKey()方法可以获得密钥。其类型为SecretKey类型,可用于以后的加密和解密。在本程序中用于生成密钥的代码如下所示:
    SecretKeysk=kg. generateKey( );

3.代码

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class rw36 {

	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		KeyGenerator kg =KeyGenerator.getInstance("DESede");//获取密钥生成器
		kg.init(168);//初始化密钥生成器
		SecretKey sk=kg.generateKey();//生成密钥
		FileOutputStream fos=new FileOutputStream("key1.dat");//将密钥保存在key1.dat文件中
		ObjectOutputStream b=new ObjectOutputStream(fos);
		b.writeObject(sk);
	}

}

二、CBC方式的加密

CBC使用一个8个字节的随机数(称为初始向量,IV)来加密第一个分组,然后使用得到的密文加密第二个分组,加密第二个分组得到的密文再加密第三个分组,……。这样,即使两个分组相同,得到的密文也不同。本实例演示了使用CBC加密方式以及初始向量进行加密的编程步骤。

1.原理

  • 生成密钥。
  • 生成初始向量。
  • 获取密码器。
  • 初始化密码器,并执行加密。

2.语法

  • 在本程序主要是通过下面的语句来获取密钥:
    FileinputStrean f1=nev FileInputStream(path);//获取密钥ObjectInputStream b=new ObjectInputstream(f1);//创建对象输入流
    Key k=(Key)b.readObject()://ObjectInputStream读取对象
  • 使用CBC方式首先要生成初始向量,然后在获取密码器对象时通过getInstance()方法的参数设定加密方式。在本程序中主要是通过下面的语句来生成初始向量的,该语句利用随机数生成的byte数组为初始值建IvParameterSpec对象。
    Ivparameterspec iv=new IvParameterSpec(rand):
  • 在获取密码器时,通过getInstance()方法的参数指定加密方式,该参数DESete/CBC/PKCS5padding由3个参数组成。其中第1个参数DESede代表所用的加密算法:第2个参数CBC即加密模式,除了CBC外,还有NONE、ECB、CFB、OFB和PCBC等可以用,第3个参数为填充模式,对称加密常用的填充方式称为PKCS#5 padding,如果加密算法不进行填充,则填充方式为No padding。
  • 一切准备工作就绪,接下来,就需要执行加密操作了。与前面的程序相比、在其参数中增加了一项初始化向量,即第2步得到的iv。执行加密时同样使用doFinal()方法对字节数组进行加密。具体代码如下所示
    Cipher cp=Cipher.getInstance(“DESede/CBC/PKCS5Padding”);
    cp.init(Cipher.ENCRYPT_MODE,k,iv);
    byte ptext[]=s.getBytes("UTF8");
    Byte ctext[]=cp.doFinal(ptext);

3.代码

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 rw3601 {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		String s="You can not be forgiven, but it should not be forgotten.";
		String path=System.getProperty("user.dir")+"//key1.dat";//得到密钥的路径
		FileInputStream f1=new FileInputStream(path);//获取密钥
		ObjectInputStream b=new ObjectInputStream(f1);//创建对象输入流
		Key k=(Key)b.readObject();//从ObjectInputStream读取对象
		//
		byte[] rand=new byte[8];
		Random r=new Random();//创建随机数生成器
		r.nextBytes(rand);//生成随机字节并将其置于rand字节数组中
		IvParameterSpec iv=new IvParameterSpec(rand);
		//使用rand中的字节作为IV来初始化一个IvParameterSpec对象
		//加密
		Cipher cp=Cipher.getInstance("DESede/CBC/PKCS5Padding");
		cp.init(Cipher.ENCRYPT_MODE, k,iv);
		byte ptext[]=s.getBytes("UTF8");
		byte ctext[]=cp.doFinal(ptext);
		//打印加密结果
		System.out.println("CBC方式输出加密结果为:");
		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);
	}
}

三、CBC方式的解密

在上文中利用CBC方式对字符串进行了加密操作。光有加密操作还不行,同样解密操作也是必不可少的。本实例演示了使用CBC解密方式以及初始向量进行解密的编程步骤。

1.原理

  • 取出向量。
  • 密文和密钥的获取。
  • 获取密码器。

2.语法

  • 在本程序中获取初始向量可以使用文件输入流的read()方法从文件EncCBC.dat中读取8个字节的对应初始向量的随机数,并用其创建IvParameterSpec对象。
  • 由于 EncCBC. dat中剩余部分为加密结果,因此使用文件输入流的available()方法判断剩余字节的数量,并创建相应大小的字节数组,读入数据。密钥必须和加密时所用的密钥相同。
  • 进行解密的操作与加密的相同,只是在初始化密码器时使用Cipher.DECRYPT_MODE,表明进行解密。

3.代码

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;

public class rw3602 {

	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		String path=System.getProperty("user.dir")+"//key1.dat";//得到密钥的路径
		FileInputStream in=new FileInputStream("EncCBC.dat");//获取密文
		byte[] rand=new byte[8];
		in.read(rand);
		IvParameterSpec iv=new IvParameterSpec(rand);//获取初始向量
		int num=in.available();
		byte[] ctext=new byte[num];
		in.read(ctext);
		FileInputStream in1=new FileInputStream(path);//获取密钥
		ObjectInputStream b=new ObjectInputStream(in1);//
		Key k=(Key)b.readObject();
		//获取密码器,执行解密
		Cipher cp=Cipher.getInstance("DESede/CBC/PKCS5Padding");
		cp.init(Cipher.DECRYPT_MODE, k,iv);
		byte[] ptext=cp.doFinal(ctext);
		String p=new String(ptext,"UTF8");
		System.out.println("CBC方式解密结果为:");
		System.out.println(p);
	}

}

四、运行结果

编译后运行结果:
对称密钥的生成:
在这里插入图片描述
CBC加密后结果:
JAVA——CBC方式的解密与加密_第1张图片
CBC解密后结果:
在这里插入图片描述
运行后结果:
对称密钥的生成:
在这里插入图片描述
CBC加密后结果:
JAVA——CBC方式的解密与加密_第2张图片

你可能感兴趣的:(JAVA)