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 Test
extends JFrame
{
public static final int WIDTH = 550;
public static final int HEIGHT = 200;
public static void main
( String args
[] )
{
Test fe = new Test();
fe.show();
}
Test()
{
this.setSize ( WIDTH, HEIGHT );
this.
setDefaultCloseOperation ( JFrame.
EXIT_ON_CLOSE );
this.setResizable ( false );
this.setLocation ( ( screenSize.width - WIDTH ) / 2,
( screenSize.height - HEIGHT ) / 2 );
this.setTitle ( "文件加密器(TriDES)" );
final FilePanel fp = new FilePanel ( "文件选择" );
c.add ( fp );
final KeyPanel pp = new KeyPanel ( "密码" );
c.add ( pp );
c.add ( jbE );
{
{
File file
= new File ( fp.
getFileName() );
if ( file.exists() )
encrypt ( file.getAbsoluteFile(), pp.getKey() );
else
}
} );
c.add ( jbD );
{
{
File file
= new File ( fp.
getFileName() );
if ( file.exists() )
decrypt ( file.getAbsoluteFile(), pp.getKey() );
else
}
} );
}
/**
* 加密函数 输入: 要加密的文件,密码(由0-F组成,共48个字符,表示3个8位的密码)如:
* AD67EA2F3BE6E5ADD368DFE03120B5DF92A8FD8FEC2F0746 其中: AD67EA2F3BE6E5AD
* DES密码一 D368DFE03120B5DF DES密码二 92A8FD8FEC2F0746 DES密码三 输出:
* 对输入的文件加密后,保存到同一文件夹下增加了".tdes"扩展名的文件中。
*/
{
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 ) );
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";
for ( int i = 0; i < bytOut.length; i++ )
{
fos.write ( ( int ) bytOut[i] );
}
fos.close();
}
else
JOptionPane.
showMessageDialog ( this,
"密码长度必须等于48!",
"错误信息",
}
{
e.printStackTrace();
}
}
/**
* 解密函数 输入: 要解密的文件,密码(由0-F组成,共48个字符,表示3个8位的密码)如:
* AD67EA2F3BE6E5ADD368DFE03120B5DF92A8FD8FEC2F0746 其中: AD67EA2F3BE6E5AD
* DES密码一 D368DFE03120B5DF DES密码二 92A8FD8FEC2F0746 DES密码三 输出:
* 对输入的文件解密后,保存到用户指定的文件中。
*/
{
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,
"不是合法的加密文件!",
"提示",
return;
}
chooser.
setCurrentDirectory ( new File ( "." ) );
chooser.
setSelectedFile ( new File ( strPath
) );
// 用户指定要保存的文件
int ret = chooser.showSaveDialog ( this );
{
byte[] bytK1 = getKeyByStr ( sKey.substring ( 0, 16 ) );
byte[] bytK2 = getKeyByStr ( sKey.substring ( 16, 32 ) );
byte[] bytK3 = getKeyByStr ( sKey.substring ( 32, 48 ) );
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();
for ( int i = 0; i < bytOut.length; i++ )
{
fos.write ( ( int ) bytOut[i] );
}
fos.close();
}
}
else
JOptionPane.
showMessageDialog ( this,
"密码长度必须等于48!",
"错误信息",
}
{
JOptionPane.
showMessageDialog ( this,
"解密失败,请核对密码!",
"提示",
}
}
/**
* 用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++ )
{
+ 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
{
{
this.add ( label );
this.add ( fileText );
this.add ( chooseButton );
clickAction ca = new clickAction ( this );
chooseButton.addActionListener ( ca );
}
{
return jtf.getText();
}
{
{
cmpt = c;
}
{
chooser.
setCurrentDirectory ( new File ( "." ) );
int ret = chooser.showOpenDialog ( cmpt );
{
jtf.setText ( chooser.getSelectedFile().getPath() );
}
}
}
}
/**
* 密码生成组件。
*/
{
{
this.add ( label );
this.add ( fileText );
this.add ( chooseButton );
clickAction ca = new clickAction ( this );
chooseButton.addActionListener ( ca );
}
// 返回生成的密码(48个字符长度)
{
return jtf.getText();
}
{
{
cmpt = c;
}
{
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();
jtf.setText ( getByteStr ( bytK1 ) + getByteStr ( bytK2 )
+ getByteStr ( bytK3 ) );
}
{
e.printStackTrace();
}
}
private String getByteStr
( byte[] byt
)
{
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
)
{
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;
}
}
}