天天看點

Java實作三重DES加密算法

資訊安全原理課,本以為會學刺激的攻防,各種注入滲透,然而事實上學的是加密解密。下面代碼是抄書的一個實驗。

本着學習DES算法的心态我手敲了一遍,然而完全就是寫界面,核心算法用的是包裡的。。

anyway,既然代碼已經敲出來了就貼一下吧,java 寫的一個桌面版程式,雖然醜了點,但也不是太難寫。

代碼很備援,寫這段代碼的人程式能力肯定不行,但是我也沒去改啦:

import java.awt.*;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.swing.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;



public class FileEncrypter extends JFrame{
    public static void main(String[] args) {
        FileEncrypter fe = new FileEncrypter();
        fe.show();
    }

    FileEncrypter(){
        this.setSize(550,200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocation(400,300);
        this.setTitle("吟遊詩人--3DES加密工具");
        Container c = this.getContentPane();
        c.setLayout(new FlowLayout());
        JLabel label = new JLabel("選擇檔案");
        c.add(label);
        final JTextField fileText = new JTextField(35);
        c.add(fileText);

        JButton chooseButton = new JButton("浏覽");
        chooseButton.addActionListener(new ActionListener(){
            //浏覽按鈕的點選事件監聽
            @Override
            public void actionPerformed(ActionEvent e){
                JFileChooser chooser = new JFileChooser();
                chooser.setCurrentDirectory(new File("."));
                int result = chooser.showOpenDialog(null);
                if(result == JFileChooser.APPROVE_OPTION){
                    //獲得檔案絕對路徑
                    String path = chooser.getSelectedFile().getAbsolutePath();
                    fileText.setText(path);
                }
            }
        });

        c.add(chooseButton);
        JLabel label2 = new JLabel("秘鑰(24個字元):");
        c.add(label2);
        final JTextField keyText = new JTextField(35);
        c.add(keyText);
        JButton jbe = new JButton("加密");
        c.add(jbe);
        jbe.addActionListener(new ActionListener(){
            //以下編寫"加密"按鈕的監聽和事件
            @Override
            public void actionPerformed(ActionEvent event) {
                String wenjian,miyao;
                wenjian = fileText.getText();
                miyao = keyText.getText();
                if("".equals(wenjian) || wenjian == null){
                    JOptionPane.showMessageDialog(null,"請選擇檔案!","提示",JOptionPane.OK_OPTION);
                }else{
                    if("".equals(miyao) || miyao == null){
                        JOptionPane.showMessageDialog(null,"請輸入24位元組秘鑰!","提示",JOptionPane.OK_OPTION);
                    }else{
                        if(miyao.length() != 24){
                            JOptionPane.showMessageDialog(null, "秘鑰必須為24位元組!","提示",JOptionPane.OK_OPTION);
                        }else{
                            //将三個秘鑰分别 存入三個位元組型數組中
                            byte[] key1 = miyao.substring(0,8).getBytes();
                            byte[] key2 = miyao.substring(8,16).getBytes();
                            byte[] key3 = miyao.substring(16,24).getBytes();

                            File file = new File(wenjian);
                            //讀取明文并存入位元組型數組plain中
                            byte[] plain = bytefromfile(file);

                            try {
                                byte[] bytOut = encryptByDES(encryptByDES(encryptByDES(plain,key1),key2),key3);
                                String fileOut = wenjian + ".tdes";
                                FileOutputStream fos = new FileOutputStream(fileOut);
                                for(int i = 0; i < bytOut.length; i++){
                                    fos.write((int)bytOut[i]);
                                }
                                fos.close();
                                JOptionPane.showMessageDialog(null,"加密成功!","提示",JOptionPane.INFORMATION_MESSAGE);
                            } catch (Exception e) {
                                //e.printStackTrace();
                                JOptionPane.showMessageDialog(null,"加密失敗!請檢查檔案或者秘鑰","提示",JOptionPane.OK_OPTION);
                            }

                        }
                    }
                }
            }

        });


        JButton jbD = new JButton("解密");
        c.add(jbD);
        //解密按鈕點選事件
        jbD.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent arg0) {
                String wenjian,wenjian1,miyao;
                wenjian = fileText.getText();
                miyao = keyText.getText();
                if("".equals(wenjian) || wenjian == null){
                    JOptionPane.showMessageDialog(null,"請選擇檔案!","提示",JOptionPane.OK_OPTION);
                    return;
                }
                if(wenjian.substring(wenjian.length() - 5).toLowerCase().equals(".tdes")){
                    if(miyao.length()!=24){
                        JOptionPane.showMessageDialog(null, "秘鑰必須為24位元組!","提示",JOptionPane.OK_OPTION);
                        return;
                    }else{
                        wenjian1 = wenjian.substring(0,wenjian.length() - 5);
                        JFileChooser chooser = new JFileChooser();
                        chooser.setCurrentDirectory(new File("."));
                        //使用者指定要儲存的檔案的位置
                        chooser.setSelectedFile(new File(wenjian1));
                        int ret = chooser.showSaveDialog(null);
                        if(ret == 0){
                            byte[] key1 = miyao.substring(0,8).getBytes();
                            byte[] key2 = miyao.substring(8,16).getBytes();
                            byte[] key3 = miyao.substring(16,24).getBytes();

                            File file = new File(wenjian);
                            //讀取密文
                            byte[] miwen = bytefromfile(file);
                            try{
                                //解密
                                byte[] bytOut = decryptByDES(decryptByDES(decryptByDES(miwen,key3),key2),key1);

                                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(null, "解密成功!","提示",JOptionPane.INFORMATION_MESSAGE);

                            }catch (Exception e) {
                                JOptionPane.showMessageDialog(null, "解密失敗!請檢查檔案或秘鑰","提示",JOptionPane.OK_OPTION);
                            }


                        }
                    }
                }else{
                    JOptionPane.showMessageDialog(null, "不是合法的加密檔案!","提示",JOptionPane.OK_OPTION);
                }
            }

        });



    }


    //從輸入的檔案中讀取位元組,儲存于TextofFile數組中,并傳回
    private byte[] bytefromfile(File filein){
        byte[] TextofFile = new byte[(int)filein.length()];
        try{
            FileInputStream fin = new FileInputStream(filein);
            for(int i = 0; i < filein.length(); i++){
                TextofFile[i] = (byte)fin.read();
            }
            fin.close();
        }catch(IOException e){
            e.printStackTrace();
        }
        return TextofFile;
    }

    //根據輸入的明文進行加密 
    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);
    }

    //根據密文和秘鑰進行解密
    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);
    }


}