import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
/**
文件名:fileencrypter.java
jdk:1.40以上
说明:文件加密
加密方法:三重des加密
加密过程:对选中的文件加密后在同文件夹下生成一个增加了".tdes"
扩展名的加密文件
解密过程:对选中的加密文件(必须有".tdes"扩展名)进行解密
*/
public class fileencrypter extends jframe{
public static final int width = 550;
public static final int height = 200;
public static void main(string args[]) {
fileencrypter fe = new fileencrypter();
fe.show();
}
fileencrypter(){
this.setsize(width,height);
this.setdefaultcloseoperation(jframe.exit_on_close);
this.setresizable(false);
toolkit tk = toolkit.getdefaulttoolkit();
dimension screensize = tk.getscreensize();
this.setlocation((screensize.width – width)/2,
(screensize.height – height)/2);
this.settitle("文件加密器(trides)");
container c = this.getcontentpane();
c.setlayout( new flowlayout());
final filepanel fp = new filepanel("文件选择");
c.add(fp);
final keypanel pp = new keypanel("密码");
c.add(pp);
jbutton jbe = new jbutton("加密");
c.add(jbe);
jbe.addactionlistener(new actionlistener(){
public void actionperformed(actionevent event){
file file = new file(fp.getfilename());
if (file.exists())
encrypt(file.getabsolutefile(),pp.getkey());
else
joptionpane.showmessagedialog(
null,"请选择文件!","提示",joptionpane.ok_option);
}
});
jbutton jbd = new jbutton("解密");
c.add(jbd);
jbd.addactionlistener(new actionlistener(){
public void actionperformed(actionevent event){
file file = new file(fp.getfilename());
if (file.exists())
decrypt(file.getabsolutefile(),pp.getkey());
else
joptionpane.showmessagedialog(
null,"请选择文件!","提示",joptionpane.ok_option);
}
});
}
/**
加密函数
输入:
要加密的文件,密码(由0-f组成,共48个字符,表示3个8位的密码)如:
ad67ea2f3be6e5add368dfe03120b5df92a8fd8fec2f0746
其中:
ad67ea2f3be6e5ad des密码一
d368dfe03120b5df des密码二
92a8fd8fec2f0746 des密码三
输出:
对输入的文件加密后,保存到同一文件夹下增加了".tdes"扩展名的文件中。
*/
private void encrypt(file filein,string skey){
try{
if(skey.length() == 48){
byte[] bytk1 = getkeybystr(skey.substring(0,16));
byte[] bytk2 = getkeybystr(skey.substring(16,32));
byte[] bytk3 = getkeybystr(skey.substring(32,48));
fileinputstream fis = new fileinputstream(filein);
byte[] bytin = new byte[(int)filein.length()];
for(int i = 0;i<filein.length();i++){
bytin[i] = (byte)fis.read();
}
//加密
byte[] bytout = encryptbydes(encryptbydes(
encryptbydes(bytin,bytk1),bytk2),bytk3);
string fileout = filein.getpath() + ".tdes";
fileoutputstream fos = new fileoutputstream(fileout);
for(int i = 0;i<bytout.length;i++){
fos.write((int)bytout[i]);
}
fos.close();
joptionpane.showmessagedialog(
this,"加密成功!","提示",joptionpane.ok_option);
}else
joptionpane.showmessagedialog(
this,"密码长度必须等于48!","错误信息",joptionpane.error_message);
}catch(exception e){
e.printstacktrace();
}
}
/**
解密函数
输入:
要解密的文件,密码(由0-f组成,共48个字符,表示3个8位的密码)如:
ad67ea2f3be6e5add368dfe03120b5df92a8fd8fec2f0746
其中:
ad67ea2f3be6e5ad des密码一
d368dfe03120b5df des密码二
92a8fd8fec2f0746 des密码三
输出:
对输入的文件解密后,保存到用户指定的文件中。
*/
private void decrypt(file filein,string skey){
try{
if(skey.length() == 48){
string strpath = filein.getpath();
if(strpath.substring(strpath.length()-5).tolowercase().equals(".tdes"))
strpath = strpath.substring(0,strpath.length()-5);
else{
joptionpane.showmessagedialog(
this,"不是合法的加密文件!","提示",joptionpane.ok_option);
return;
}
jfilechooser chooser = new jfilechooser();
chooser.setcurrentdirectory(new file("."));
chooser.setselectedfile(new file(strpath));
//用户指定要保存的文件
int ret = chooser.showsavedialog(this);
if(ret==jfilechooser.approve_option){
byte[] bytk1 = getkeybystr(skey.substring(0,16));
byte[] bytk2 = getkeybystr(skey.substring(16,32));
byte[] bytk3 = getkeybystr(skey.substring(32,48));
fileinputstream fis = new fileinputstream(filein);
byte[] bytin = new byte[(int)filein.length()];
for(int i = 0;i<filein.length();i++){
bytin[i] = (byte)fis.read();
}
//解密
byte[] bytout = decryptbydes(decryptbydes(
decryptbydes(bytin,bytk3),bytk2),bytk1);
file fileout = chooser.getselectedfile();
fileout.createnewfile();
fileoutputstream fos = new fileoutputstream(fileout);
for(int i = 0;i<bytout.length;i++){
fos.write((int)bytout[i]);
}
fos.close();
joptionpane.showmessagedialog(
this,"解密成功!","提示",joptionpane.ok_option);
}
}else
joptionpane.showmessagedialog(
this,"密码长度必须等于48!","错误信息",joptionpane.error_message);
}catch(exception e){
joptionpane.showmessagedialog(
this,"解密失败,请核对密码!","提示",joptionpane.ok_option);
}
}
/**
用des方法加密输入的字节
bytkey需为8字节长,是加密的密码
*/
private byte[] encryptbydes(byte[] bytp,byte[] bytkey) throws exception{
deskeyspec desks = new deskeyspec(bytkey);
secretkeyfactory skf = secretkeyfactory.getinstance("des");
secretkey sk = skf.generatesecret(desks);
cipher cip = cipher.getinstance("des");
cip.init(cipher.encrypt_mode,sk);
return cip.dofinal(bytp);
}
/**
用des方法解密输入的字节
bytkey需为8字节长,是解密的密码
*/
private byte[] decryptbydes(byte[] byte,byte[] bytkey) throws exception{
deskeyspec desks = new deskeyspec(bytkey);
secretkeyfactory skf = secretkeyfactory.getinstance("des");
secretkey sk = skf.generatesecret(desks);
cipher cip = cipher.getinstance("des");
cip.init(cipher.decrypt_mode,sk);
return cip.dofinal(byte);
}
/**
输入密码的字符形式,返回字节数组形式。
如输入字符串:ad67ea2f3be6e5ad
返回字节数组:{173,103,234,47,59,230,229,173}
*/
private byte[] getkeybystr(string str){
byte[] bret = new byte[str.length()/2];
for(int i=0;i<str.length()/2;i++){
integer itg =
new integer(16*getchrint(str.charat(2*i)) + getchrint(str.charat(2*i+1)));
bret[i] = itg.bytevalue();
}
return bret;
}
/**
计算一个16进制字符的10进制值
输入:0-f
*/
private int getchrint(char chr){
int iret=0;
if(chr=="0".charat(0)) iret = 0;
if(chr=="1".charat(0)) iret = 1;
if(chr=="2".charat(0)) iret = 2;
if(chr=="3".charat(0)) iret = 3;
if(chr=="4".charat(0)) iret = 4;
if(chr=="5".charat(0)) iret = 5;
if(chr=="6".charat(0)) iret = 6;
if(chr=="7".charat(0)) iret = 7;
if(chr=="8".charat(0)) iret = 8;
if(chr=="9".charat(0)) iret = 9;
if(chr=="a".charat(0)) iret = 10;
if(chr=="b".charat(0)) iret = 11;
if(chr=="c".charat(0)) iret = 12;
if(chr=="d".charat(0)) iret = 13;
if(chr=="e".charat(0)) iret = 14;
if(chr=="f".charat(0)) iret = 15;
return iret;
}
}
/**
文件选择组件。
*/
class filepanel extends jpanel{
filepanel(string str){
jlabel label = new jlabel(str);
jtextfield filetext = new jtextfield(35);
jbutton choosebutton = new jbutton("浏览…");
this.add(label);
this.add(filetext);
this.add(choosebutton);
clickaction ca = new clickaction(this);
choosebutton.addactionlistener(ca);
}
public string getfilename(){
jtextfield jtf = (jtextfield)this.getcomponent(1);
return jtf.gettext();
}
private class clickaction implements actionlistener{
clickaction(component c){
cmpt = c;
}
public void actionperformed(actionevent event){
jfilechooser chooser = new jfilechooser();
chooser.setcurrentdirectory(new file("."));
int ret = chooser.showopendialog(cmpt);
if(ret==jfilechooser.approve_option){
jpanel jp = (jpanel)cmpt;
jtextfield jtf = (jtextfield)jp.getcomponent(1);
jtf.settext(chooser.getselectedfile().getpath());
}
}
private component cmpt;
}
}
/**
密码生成组件。
*/
class keypanel extends jpanel{
keypanel(string str){
jlabel label = new jlabel(str);
jtextfield filetext = new jtextfield(35);
jbutton choosebutton = new jbutton("随机产生");
this.add(label);
this.add(filetext);
this.add(choosebutton);
clickaction ca = new clickaction(this);
choosebutton.addactionlistener(ca);
}
//返回生成的密码(48个字符长度)
public string getkey(){
jtextfield jtf = (jtextfield)this.getcomponent(1);
return jtf.gettext();
}
private class clickaction implements actionlistener{
clickaction(component c){
cmpt = c;
}
public void actionperformed(actionevent event){
try{
keygenerator kg = keygenerator.getinstance("des");
kg.init(56);
key ke = kg.generatekey();
byte[] bytk1 = ke.getencoded();
ke = kg.generatekey();
byte[] bytk2 = ke.getencoded();
ke = kg.generatekey();
byte[] bytk3 = ke.getencoded();
jpanel jp = (jpanel)cmpt;
jtextfield jtf = (jtextfield)jp.getcomponent(1);
jtf.settext(getbytestr(bytk1)+getbytestr(bytk2)+getbytestr(bytk3));
}catch(exception e){
e.printstacktrace();
}
}
private string getbytestr(byte[] byt){
string strret = "";
for(int i=0;i<byt.length;i++){
//system.out.println(byt[i]);
strret += gethexvalue((byt[i]&240)/16);
strret += gethexvalue(byt[i]&15);
}
return strret;
}
private string gethexvalue(int s){
string sret=null;
switch (s){
case 0: sret = "0";break;
case 1: sret = "1";break;
case 2: sret = "2";break;
case 3: sret = "3";break;
case 4: sret = "4";break;
case 5: sret = "5";break;
case 6: sret = "6";break;
case 7: sret = "7";break;
case 8: sret = "8";break;
case 9: sret = "9";break;
case 10: sret = "a";break;
case 11: sret = "b";break;
case 12: sret = "c";break;
case 13: sret = "d";break;
case 14: sret = "e";break;
case 15: sret = "f";
}
return sret;
}
private component cmpt;
}
}
