- 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 );
- 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;
- }
- }
来源: http://www.phpxs.com/code/1002409/