Java 对文件加密解密(AES,DES)
待加密文件:C:/myjava/Hello.java
(1)编写一个Java程序,实现对命令行输入的信息进行加解密处理,具体实现以下功能:
加密“文件名1”对应的文件,并将结果存储到“文件名2 ”对应的文件
解密“文件名1”对应的文件,并将结果存储到“文件名2 ”对应的文件
其中:
1) 加密算法:AES
2) 加密模式:CBC
3) 填充方式:PKCS5Padding/NoPadding
package question1;
import java.util.* ;
import java.io.*;
import java.security.*;
import javax.crypto.* ;
import javax.crypto.spec.* ;
public class question1 {
public static void main (String args[]) throws Exception {
String s=Read("C:/myjava/Hello.java"); //读取待加密文件
KeyGenerator kg = KeyGenerator.getInstance("AES"); //随机生成秘钥
kg.init(256); //长度为256
SecretKey sk = kg.generateKey();
FileOutputStream file=new FileOutputStream ("Key1.dat") ; //存储密钥
ObjectOutputStream b1=new ObjectOutputStream (file);
b1.writeObject (sk) ;
Encryption("Key1.dat" ,s,"AES_E.dat"); //用Key1.dat加密s,并将结果存储在AES_E.dat
System.out.println () ;
Decryption("Key1.dat","AES_E.dat","AES_D.dat"); //用Key1.dat解密AES_E.dat,并将结果存储在AES_D.dat
public static void Encryption (String str1,String s,String s2) throws Exception {
//str1 为密钥文件地址 ,str2 为待加密数据,s2为用于存储加密后数据的文件
FileInputStream f1=new FileInputStream (str1);
ObjectInputStream b=new ObjectInputStream(f1);
Key k=(Key) b.readObject (); //获取密钥
//生成初始化向量
byte[] rand=new byte [16] ;
Random r=new Random ( ) ;
r.nextBytes (rand) ;
IvParameterSpec iv=new IvParameterSpec (rand) ; //加密
Cipher cp=Cipher.getInstance ("AES /CBC/PKCS5Padding" ) ;
cp.init (Cipher.ENCRYPT_MODE,k, iv) ;
byte ptext [ ]=s.getBytes ("UTF8");
byte ctext [ ]=cp.doFinal (ptext) ; //打印加密结果
System.out.println("加密结果为:");
for(int i=0;i<ctext.length;i++){
System.out.print (ctext [i] +" ");
//保存加密结果
FileOutputStream f2=new FileOutputStream ( s2) ;
f2.write (rand) ;
f2.write(ctext);
public static void Decryption (String str1,String str2,String str3) throws Exception {
//str1 为密钥文件地址 ,str2为待解密的文件,str3为用于存储解密后数据的文件
//获取初始向量
FileInputStream f=new FileInputStream ( str2) ;
byte [] rand2=new byte[16] ;
f.read (rand2) ;
IvParameterSpec iv2=new IvParameterSpec (rand2) ; //获取密文
int num=f.available ( );
byte[ ] ctext2=new byte [num] ;
f.read (ctext2);
//获取密钥
FileInputStream f3=new FileInputStream ( str1 ) ;
ObjectInputStream b2=new ObjectInputStream(f3);
Key k2=(Key ) b2.readObject ( ) ;
//获取密码器,执行解密
Cipher cp2=Cipher.getInstance ("AES /CBC/ PKCS5Padding" ) ;
cp2.init (Cipher.DECRYPT_MODE,k2, iv2) ;
byte []ptext2=cp2.doFinal (ctext2 ) ;
String p=new String(ptext2 ,"UTF8") ;
System.out.println ("解密结果为:") ;
System.out.println (p) ; //输出解密结果
FileOutputStream f2=new FileOutputStream ( str3) ; //存储解密结果
f2.write (rand2) ;
f2.write(ctext2);
public static String Read (String str1) //读取待加密文件
//String str1="C:/myjava/Hello.java";
File file=new File(str1);
//根据路径创建File类对象--这里路径即使错误也不会报错,因为只是产生File对象,还并未与计算机文件读写有关联
byte[] bytes=new byte[(int) file.length()];
//根据文件的长度创建byte数组的长度
FileInputStream fileInput=new FileInputStream(file);
//与根据File类对象的所代表的实际文件建立链接创建fileInputStream对象
try {
int data = fileInput.read(bytes,0,(int) file.length()) ;
String str=new String(bytes,0,data);
return str;
//System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
} catch (FileNotFoundException e)
e.printStackTrace();
System.out.println("文件不存在或者文件不可读或者文件是目录");
return null;
(2)编写一个Java程序,实现PBE算法加解密功能,具体实现以下功能:
加密“文件名1”对应的文件,并将结果存储到“文件名2 ”对应的文件
解密“文件名1”对应的文件,并将结果存储到“文件名2 ”对应的文件
其中:
1) 加密算法:PBEWithMD5AndDES
2) 迭代次数:1000
package question2;
import java.util.* ;
import java.io.*;
import java.security.*;
import javax.crypto.* ;
import javax.crypto.spec.* ;
public class question2 {
public static void main (String args[]) throws Exception {
String s=Read("C:/myjava/Hello.java"); //读取待加密文件
String password="12fw32"; //口令
Encryption(password ,s,"DES_E.dat"); //用password为口令加密s,并将结果存储在DES_E.dat
System.out.println () ;
Decryption(password,"DES_E.dat","DES_D.dat"); //用password解密DES_E.dat,并将结果存储在DES_D.dat
public static void Encryption (String password,String s,String s2) throws Exception {
//password为口令 ,s 为待加密数据,s2为用于存储加密后数据的文件
char[] passwd=password.toCharArray( ); //由口令生成密钥
PBEKeySpec pbks=new PBEKeySpec(passwd);
SecretKeyFactory kf=SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey k=kf.generateSecret(pbks);
byte[] salt=new byte[8]; //生成随机数(盐)
Random r=new Random( );
r.nextBytes(salt);
Cipher cp=Cipher.getInstance("PBEWithMD5AndDES"); //创建并初始化密码器
PBEParameterSpec ps=new PBEParameterSpec(salt,1000);
cp.init(Cipher.ENCRYPT_MODE, k,ps);
byte ptext[]=s.getBytes("UTF8"); //获取明文,执行加密
byte ctext[]=cp.doFinal(ptext);
//将盐和加密结果合并在一起保存为密文
FileOutputStream f=new FileOutputStream (s2 ) ;
f.write (salt);
f.write (ctext); //打印盐的值
System.out.println ("盐的值为:");
for(int i=0 ; i<salt.length;i++){
System.out.print (salt [ i] +" ");
System.out.println ("");
System.out.println("加密结果为:"); //打印加密结果
for(int i=0;i<ctext.length;i++){
System.out.print (ctext [i] +" ");
public static void Decryption (String password,String str2,String str3) throws Exception {
//password为口令 ,str2为待解密的文件,str3为用于存储解密后数据的文件
char[] passwd=password.toCharArray( ); //读取口令并生成密钥
PBEKeySpec pbks=new PBEKeySpec(passwd);
SecretKeyFactory kf=
SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey k=kf.generateSecret(pbks);
byte[] salt=new byte[8]; //获取随机数(盐)
FileInputStream f=new FileInputStream(str2);
f.read(salt);
int num=f.available(); //获取加密结果
byte[ ] ctext=new byte[num];
f.read(ctext);
Cipher cp=Cipher.getInstance("PBEWithMD5AndDES"); //创建密码器,执行解密
PBEParameterSpec ps=new PBEParameterSpec(salt,1000);
cp.init(Cipher.DECRYPT_MODE, k,ps);
byte ptext[]=cp.doFinal(ctext);
String p=new String(ptext ,"UTF8") ;
System.out.println ("解密结果为:") ;
System.out.println (p) ; //输出解密结果
FileOutputStream f2=new FileOutputStream (str3) ; //存储解密结果到str3
f2.write (salt) ;
f2.write(ctext);
public static String Read (String str1) //读取待加密文件
//String str1="C:/myjava/Hello.java";
File file=new File(str1);
//根据路径创建File类对象--这里路径即使错误也不会报错,因为只是产生File对象,还并未与计算机文件读写有关联
byte[] bytes=new byte[(int) file.length()];
//根据文件的长度创建byte数组的长度
FileInputStream fileInput=new FileInputStream(file);
//与根据File类对象的所代表的实际文件建立链接创建fileInputStream对象
try {
int data = fileInput.read(bytes,0,(int) file.length()) ;
String str=new String(bytes,0,data);
return str;
//System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
} catch (FileNotFoundException e)
e.printStackTrace();
System.out.println("文件不存在或者文件不可读或者文件是目录");