Java使用Cipher类,InputStream,OnputStream实现文件的加解密

         Java使用Cipher类,InputStream,OnputStream实现文件的加解密

题目要求:

说明:注释我觉得挺多的了,应该可以看懂。代码具体实现与题目有一点点出入,关系不大。重要的是根据中文API文档查找到相关类,相关方法的使用方法进行学习,运用后才能真正理解。

分享一下java的中文API文档

链接:https://pan.baidu.com/s/16UI6v2bnaYagFHxbRObISw 
提取码:82xv 
 

代码实现:

package fileOperation;

import java.awt.HeadlessException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Scanner;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.swing.JFileChooser;


public class encryAndDecry {   
	  Key key;   //类成员
	  static String ALGORITHM = "";
	  public encryAndDecry(String str,String algorithm) {   
	    getKey(str,algorithm);//生成密钥   
	  }    
	  public void getKey(String strKey,String ALGORITHM) {    //获取密钥
	    try {   
	        KeyGenerator _generator = KeyGenerator.getInstance(ALGORITHM); // 密钥生成器
	        _generator.init(new SecureRandom(strKey.getBytes()));   //初始化生成器
	        this.key = _generator.generateKey();     //生成密钥
	        _generator = null;      //将生成器置空
	    } catch (Exception e) {     //异常抛出
	        throw new RuntimeException("Error initializing SqlMap class. Cause: " + e);   
	    }   
	  }   
	  
	  /*
	  * 文件file进行加密并保存目标文件destFile中   
	  * @param file   要加密的文件  
	  * @param destFile 加密后存放的文件名 
	  */   
	  public void encrypt(String file, String destFile,String ALGORITHM) throws Exception {  
		long t1 = System.currentTimeMillis();  //加密前系统时间
	    Cipher cipher = Cipher.getInstance(ALGORITHM);   //用ALGORITHM算法创建一个cipher对象 
	    cipher.init(Cipher.ENCRYPT_MODE, this.key);   //初始化cipher对象,Cipher.ENCRYPT_MODE代表加密
	    InputStream is = new FileInputStream(file);   //文件输入流
	    OutputStream out = new FileOutputStream(destFile);   //文件输出流
	    CipherInputStream cis = new CipherInputStream(is, cipher);  //cipher输入流,即加密
	    //CipherInputStream由InputStream和Cipher组成,read()方法返回从底层InputStream读入但是由Cipher额外处理的数据
	    byte[] buffer = new byte[1024];   //缓冲区
	    int r;   
	    while ((r = cis.read(buffer)) > 0) {   //read返回已经读取多少个字节写进缓冲区,读取完返回-1
	        out.write(buffer, 0, r);   //从缓冲区将数据写进加密文件
	    }   
	    long t2 = System.currentTimeMillis();  //加密后系统时间
	    cis.close();   
	    is.close();   
	    out.close();   //文件关闭
	    System.out.println("加密用时:"+(t2-t1)+"ms");
	  }  
	  
	  /* 
	  * @param file 已加密的文件 
	  * @param destFile  解密后存放的文件名 
	  */   
	  public void decrypt(String file, String destFile,String ALGORITHM) throws Exception {  
		if(!file.contains("enc"))
		{
			return;
		}
		long t1 = System.currentTimeMillis();  //解密前系统时间
	    Cipher cipher = Cipher.getInstance(ALGORITHM);   
	    cipher.init(Cipher.DECRYPT_MODE, this.key);  //Cipher.DECRYPT_MODE代表解密 
	    InputStream is = new FileInputStream(file);   
	    OutputStream out = new FileOutputStream(destFile);   
	    CipherOutputStream cos = new CipherOutputStream(out, cipher);   //cipher输出流,即解密
	    byte[] buffer = new byte[1024];   //缓冲区
	    int r;   
	    while ((r = is.read(buffer)) >= 0) {   
	        System.out.println();  
	        cos.write(buffer, 0, r);   
	    }   
	    long t2 = System.currentTimeMillis();  //解密后系统时间
	    cos.close();   
	    out.close();   
	    is.close();   //文件关闭
	    System.out.println("解密用时:"+(t2-t1)+"ms");
	  }   
	  //对文件夹进行操作
	  public void folderOperation(File file,String addpath,boolean choice,encryAndDecry ead) throws Exception {
		addpath = addpath +"\\";   //如果找到文件,缺少\,如D:\test
		if(file.isDirectory())//文件夹
		{
			File f[] = file.listFiles();
			for(int i=0;i<f.length;i++)
			{
				if(f[i].isDirectory()) {  //是文件夹的话,对路径进行递归处理
					folderOperation(f[i],addpath+f[i].getName()+"\\",choice,ead); 
				}
				else {
					folderOperation(f[i], addpath+f[i].getName(),choice,ead);
				}
			}
		}
		else { //遍历到了文件
			String s[] = addpath.split("\\.");
			String restr = s[0].substring(0,s[0].length()-3);   //去掉加密文件后的enc
			if(choice)//加密
			{
				ead.encrypt(addpath, s[0]+"enc."+s[1],ALGORITHM);
			}
			else {  //解密
				ead.decrypt(addpath, restr+"dec."+s[1],ALGORITHM);
			}
		}
	}
	  public File choiceFile() {    //文件选择函数
		    JFileChooser fc = new JFileChooser();  //文件选择器
			int flag = 0;  File f = null;  
			fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); //可以选择文件或文件夹
			try{    
			        flag = fc.showOpenDialog(null);    //打开选择框
			 }   
			catch(HeadlessException head){    //异常处理
			        System.out.println("Open File Dialog ERROR!");   
			 }       
			 if(flag==JFileChooser.APPROVE_OPTION){            
			        f=fc.getSelectedFile();    //获得文件或文件夹
			 } 
			 return f;
	}
	  public static void main(String[] args) throws Exception { 
		Scanner in = new Scanner(System.in);  //标准输入扫描器对象
		System.out.println("请选择加密算法? DES/AES/DESede"); 
		ALGORITHM = in.nextLine();
		System.out.println("请输入密钥进行加密:");
		String secretKey = in.nextLine();   //从键盘输入字符串
		encryAndDecry ead = new encryAndDecry(secretKey,ALGORITHM);  //实例化对象 
		File f_en = null;  String path_en = null;   //条件初始化
		File f_de = null;  String path_de = null;
		f_en = ead.choiceFile();  //获取选择文件
		if(f_en==null)
		{
			System.out.println("文件获取失败!");
			return;
		}
		path_en = f_en.getPath(); //获取文件路径
	    System.out.println(path_en);
		if(f_en.isDirectory())  //如果是个文件夹
		{
	        ead.folderOperation(f_en,path_en,true,ead); //true表示加密
		}
		else {
			String s[] = path_en.split("\\.");   //将文件切分,取名字与后缀名
			ead.encrypt(path_en, s[0]+"enc."+s[1],ALGORITHM);  //调用加密函数
		}
		System.out.println("请输入密钥进行解密:");
		String verificationCode = in.nextLine(); //输入验证码
		in.close();    //关闭输入
		if(verificationCode.equals(secretKey))  //验证码与密钥相同
		{
			f_de = ead.choiceFile();
			if(f_de==null)
			{
				System.out.println("文件获取失败!");
				return;
			}
			path_de = f_de.getPath();
		    System.out.println(path_de);
			if(!f_de.isDirectory()) //需要解密是文件
			{
				String str[] = path_de.split("\\.");
				String tempstr = str[0].substring(0,str[0].length()-3); //去掉加密文件后的enc
				ead.decrypt(path_de, tempstr+"dec."+str[1],ALGORITHM);  //调用解密函数
				System.out.println("解密成功");
			}
			else {
				ead.folderOperation(f_de, path_de, false, ead); //false代表解密
			}
		}
		else {   //异常处理
			System.out.println("密钥错误!");
			return;
		}
	  }   
}  

参考链接:https://blog.csdn.net/m0_37671741/article/details/96450535

https://blog.csdn.net/lizijie7471619/article/details/54140064?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

https://blog.csdn.net/achuo/article/details/72190567

https://blog.csdn.net/aaqian1/article/details/89349240

https://blog.csdn.net/ganxunzou/article/details/8129652

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值