java文本文件加密解密類


原文:http://www.open-open.com/code/view/1420031154765

 

 

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;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM