RSA加解密和簽名圖形界面化


```java
package shiyan;
/**
 *下面我們開始導包 , 土話 就是 把 那個文件夾下的 什麼東西 拿來 ,我要用, 
 *java是重量級的包,javax是輕量級的包!!
 * */
import org.apache.commons.codec.binary.Base64;//Commons項目中用來處理常用的編碼方法的工具類包,例如DES、SHA1、MD5、Base64, 及 hex, metaphone, soundex 等編碼演算。
import org.apache.commons.io.IOUtils;//apache.commons模塊已經封裝了快速讀取文件內容的工具類IOUtils,在項目中可以直接使用,非常方便!
import java.util.*; //Java的實用工具類庫java.util包。在這個包中,Java提供了一些實用的方法和數據結構。
import javax.crypto.Cipher;//提供加解密功能                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            import java.io.ByteArrayOutputStream;//ByteArrayOutputStream是字節數組輸出流,在內存中創建了一個字節數組,所有發送到輸出流的數據都會保存到該字節數組的緩衝區中.
import java.security.*;//Java加密框架,裏面有不同的類,每個類定義了一種服務!!比如有:MessageDigest(生成摘要)、Signature(簽名)、KeyPairGenerator(生成公私鑰對)、AlgorithmParameters(管理算法的參數)、、
import java.security.interfaces.RSAPrivateKey;//提供的接口用於生成私鑰
import java.security.interfaces.RSAPublicKey;//提供的接口用於生成如公鑰
import java.security.spec.*;//
import java.security.spec.PKCS8EncodedKeySpec;//PKCS8格式的祕鑰(適用於java)。
import java.security.spec.X509EncodedKeySpec;//X509的標準進行加密  
import java.util.HashMap;
import java.util.Map;

import java.io.*;//提供一個合理的路徑,使得編譯器可以找到某個類(這裏是FileReader類)。
/**圖形界
 * 面化的
 * 依賴
 * 導入包*/
import java.awt.*;//包含用於創建用戶界面和繪製圖形圖像的所有類
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;

import java.awt.event.*; 

 
 
public class RSA {
    public static final String CHARSET = "UTF-8";
    public static final String RSA_ALGORITHM = "RSA";
    
    private static String securitymessage = "F:\\test\\src\\shiyan\\securitymessage";//指定程序執行結果保存的文件路徑,保存密文
    private static String securitykey = "F:\\test\\src\\shiyan\\securitykey";//保存密鑰
    private static String message = "F:\\test\\src\\shiyan\\message";//提取輸入的明文
   
    public static Map<String, String> createKeys(int keySize) {
        //爲RSA算法創建一個KeyPairGenerator對象
        KeyPairGenerator kpg;
        try 
        {
            kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
        }
 
        //初始化KeyPairGenerator對象,密鑰長度
        kpg.initialize(keySize);
        //生成密匙對
        KeyPair keyPair = kpg.generateKeyPair();
        //得到公鑰
        Key publicKey = keyPair.getPublic();
        String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
        //得到私鑰
        Key privateKey = keyPair.getPrivate();
        String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
        Map<String, String> keyPairMap = new HashMap<String, String>();
        keyPairMap.put("publicKey", publicKeyStr);
        keyPairMap.put("privateKey", privateKeyStr);
 
        return keyPairMap;
    }
 
    /**
     * 得到公鑰
     * @param publicKey 密鑰字符串(經過base64編碼)
     * @throws Exception
     */
    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通過X509編碼的Key指令獲得公鑰對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }
 
    /**
     * 得到私鑰
     * @param privateKey 密鑰字符串(經過base64編碼)
     * @throws Exception
     */
    public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通過PKCS#8編碼的Key指令獲得私鑰對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
        RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
        return key;
    }
 
    /**
     * 公鑰加密
     *
     */
    public static String publicEncrypt(String data, RSAPublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
        } catch (Exception e) {
            throw new RuntimeException("加密字符串[" + data + "]時遇到異常", e);
        }
    }
 
    /**
     * 私鑰解密
     *
     */
 
    public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
        } catch (Exception e) {
            throw new RuntimeException("解密字符串[" + data + "]時遇到異常", e);
        }
    }
 
    /**
     * 私鑰加密
     */
 
    public static String privateEncrypt(String data, RSAPrivateKey privateKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));
        } catch (Exception e) {
            throw new RuntimeException("加密字符串[" + data + "]時遇到異常", e);
        }
    }
 
    /**
     * 公鑰解密
     */
    public static String publicDecrypt(String data, RSAPublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET);
        } catch (Exception e) {
            throw new RuntimeException("解密字符串[" + data + "]時遇到異常", e);
        }
    }
 
    private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
        int maxBlock = 0;
        if (opmode == Cipher.DECRYPT_MODE) {
            maxBlock = keySize / 8;
        } else {
            maxBlock = keySize / 8 - 11;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] buff;
        int i = 0;
        try {
            while (datas.length > offSet) {
                if (datas.length - offSet > maxBlock) {
                    buff = cipher.doFinal(datas, offSet, maxBlock);
                } else {
                    buff = cipher.doFinal(datas, offSet, datas.length - offSet);
                }
                out.write(buff, 0, buff.length);
                i++;
                offSet = i * maxBlock;
            }
        } catch (Exception e) {
            throw new RuntimeException("加解密閥值爲[" + maxBlock + "]的數據時發生異常", e);
        }
        byte[] resultDatas = out.toByteArray();
    //    IOUtils.closeQuietly(out);
        return resultDatas;
    }
  
    public static void main(String[] args) throws Exception {
    	// Runtime.getRuntime().exec("cmd.exe /c start "+"C:\\Users\\banxiao\\Desktop\\大三上-各專業報告\\java程序設計實驗\\雜.txt");//將txt文件打開
    	
   
    	 System.out.println("請選擇您要生成的公私鑰位數:有512、1024、2048、4096位四種");
    	Scanner input= new Scanner(System.in);
    	int str= input.nextInt();
        Map<String, String> keyMap = RSAUtils.createKeys(str);
        String publicKey = keyMap.get("publicKey");
        String privateKey = keyMap.get("privateKey");
        System.out.println("下面是選擇"+str+"位生成的公鑰和私鑰");
    
        System.out.println("公鑰加密——私鑰解密;私鑰簽名——公鑰驗證");
       

        JFrame frame = new JFrame("一個關於RSA的加密解密窗口");
        // frame.setSize(400,400);//設置窗口大小
         // Button名稱
         JButton button0 = new JButton("瀏覽");
         JButton button1 = new JButton("加密");
         JButton button2 = new JButton("解密");
         JButton button3 = new JButton("簽名");
         JButton button4 = new JButton("驗證");
         // JTextField名稱,定義文本框的大小
         final JTextField content = new JTextField();
       //  content.setName("content");
         final JTextField pass = new JTextField();
        // content.setName("pass");
         final JTextField dpass = new JTextField();
         final JTextField sign = new JTextField();
         // content.setName("sign");
          final JTextField prove = new JTextField();

         // JLabel
         JLabel view = new JLabel("瀏覽", JLabel.CENTER);
         view.setFont(new java.awt.Font("Dialog", 1, 15));//Dialog代表字體,1代表粗0代表細,15代表字號
         view.setOpaque(true);  //設置控件是否透明的。true表示不透明,false表示透明。
         view.setBackground(Color.white);
         view.setForeground(Color.black);

         // 畫布佈局
         JPanel contentPane = new JPanel();//實例化一個面板,把其它組件添加到Jpanel中;
        // contentPane.setBackground(Color.white);
         //contentPane.setSize(1000,1000);
         contentPane.add(button0);
         contentPane.add(button1);
         contentPane.add(button2);
         contentPane.add(button3);
         contentPane.add(button4);
         contentPane.add(content);
         contentPane.add(pass);
         contentPane.add(dpass);
         contentPane.add(sign);
         contentPane.add(prove);
         contentPane.add(view);
         frame.setContentPane(contentPane);
         contentPane.setLayout(null);//設置窗體佈局

         // 按鈕大小設置(x,y,長度,寬度)
         content.setBounds(131, 4, 200, 40);
         button0.setBounds(50, 4, 80, 40);
         
         pass.setBounds(131, 50, 200, 40);
         button1.setBounds(50, 50, 80, 40);
         
         dpass.setBounds(131, 100, 200, 40);
         button2.setBounds(50, 100, 80, 40);
         
         sign.setBounds(131, 150, 200, 40);
         button3.setBounds(50, 150, 80, 40);
         
         prove.setBounds(131, 200, 200, 40);
         button4.setBounds(50, 200, 80, 40);
         
         frame.setSize(500, 500);//設置窗口大小
         frame.setVisible(true);//把窗口設置爲可見
       
      
         //瀏覽,選擇本地文件夾內容進行加密。
         button0.addActionListener( new ActionListener() 
         {
             public void actionPerformed(ActionEvent e) 
             {
                 // TODO Auto-generated method stub
            
           		JFileChooser jfc=new JFileChooser();//用於加載桌面或者某硬盤的文件,進行加密
                    if(jfc.showOpenDialog(null)==JFileChooser.APPROVE_OPTION)//這裏showDialog,彈出具有自定義 approve 按鈕的自定義文件選擇器對話框。該文件選擇器被彈下時的返回狀態:JFileChooser.CANCEL_OPTIONJFileChooser.APPROVE_OPTIONJFileChooser.ERROR_OPTION 。
                    {
                    	String file=jfc.getSelectedFile().getAbsolutePath();     	
                       // MyFileReader rf;
                  		try {
                  			int c=-1;
                  			byte[] b=new byte[10004];
                  			FileInputStream fis=new FileInputStream(file);
                  			//rf = new MyFileReader(file);
                  			while((c=fis.read(b))!=-1) {
                  				String s= new String(b,0,c);
                  				System.out.println(s);
                  				content.setText(s);
                  			}
                  			/*Scanner input=new Scanner(file);
                             while(input.hasNext()){
                          	   content.setText(input.nextLine());
                               //  System.out.println(input.nextLine());
                             }*/
                             input.close();
                  			
     						}catch (IOException e1) {
     							// TODO Auto-generated catch block
     							e1.printStackTrace();
                  			}
                  			/* 
                  			while((c=rf.read())!=-1)//讀取filte文件裏的內容直到讀完返回-1,並打印出讀取的內同。
							{
							   String encodedData = String.valueOf(c);
							  // System.out.print(encodedData);
							   content.setText(encodedData);
							
							}
                            }catch (IOException e1) {
    							// TODO Auto-generated catch block
    							e1.printStackTrace();
    						}
                            input.close();
                            while((c=rf.read())!=-1)//讀取filte文件裏的內容直到讀完返回-1,並打印出讀取的內同。
							{
							   String encodedData = String.valueOf(c);
							  // System.out.print(encodedData);
							   content.setText(encodedData);
							
							}
						/*}
                            Scanner input=new Scanner(file);
                            while(input.hasNext()){
                         	   content.setText(input.nextLine());
                              //  System.out.println(input.nextLine());
                            }
                            input.close();
                        }
                        else
                            System.out.println("No file is selected!");
                            
            
             }
                        
                        
                      MyFileReader rf = new MyFileReader();                                                                          
                        FileWriter fw1  = new FileWriter(file);
                        int c;
                  		while((c=rf.read())!=-1)//讀取filte文件裏的內容直到讀完返回-1,並打印出讀取的內同。
                  		{
                  		   String encodedData = String.valueOf(c);
                  		   fw1.write(encodedData);
                  		   fw1.flush();
                  		
                  		}
                        
                        
                   
                        while(fw1.hasNext()){
                     	   String str1 = input.nextLine().toString();
                     	   try {
                     	        pass.setText(encrypt(str1));
                     	
                     	   }catch (Exception e1) {
                                // TODO Auto-generated catch block
                                e1.printStackTrace();
                            }
                           
                        }
                        input.close();
                    }
                    else
                        System.out.println("No file is selected!");
                   
                   
              */
                    }
             }
         }
    
          );
   //加密的按鈕及內容的設置      
         button1.addActionListener(
         		new ActionListener() 
         {

             @Override
             public void actionPerformed(ActionEvent e) 
             {
                 // TODO Auto-generated method stub
                 String str1 = content.getText().toString();
                 try {
                     pass.setText(RSAUtils.publicEncrypt(str1, RSAUtils.getPublicKey(publicKey)));
                 } catch (Exception e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();
                 }
             }
         }
         		);
//解密的按鈕及內容的設置
         button2.addActionListener(new ActionListener() {

             @Override
             public void actionPerformed(ActionEvent e) {
                 // TODO Auto-generated method stub
                 String str2 = pass.getText().toString();
                 try {
                     dpass.setText(RSAUtils.privateDecrypt(str2, RSAUtils.getPrivateKey(privateKey)));
                 } catch (Exception e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();
                 }
             }
         });
         //簽名的按鈕及內容設置
         button3.addActionListener(new ActionListener() 
         {
             public void actionPerformed(ActionEvent e) 
             {
                 // TODO Auto-generated method stub
                 String str1 = content.getText().toString();
                 try {
                     sign.setText(RSAUtils.privateEncrypt(str1, RSAUtils.getPrivateKey(privateKey)));
                 } catch (Exception e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();
                 }
             }
         });

         //驗證的按鈕一內容的設置
         button4.addActionListener(new ActionListener() {

             @Override
             public void actionPerformed(ActionEvent e) {
                 // TODO Auto-generated method stub
                 String str2 = sign.getText().toString();
                 String str1 = content.getText().toString();
                 System.out.println(str1);
                 try {
                	 
                	 String str=RSAUtils.publicDecrypt(str2, RSAUtils.getPublicKey(publicKey));
                	 if(str.equals(str1))  prove.setText("驗證失敗");
                	 prove.setText("驗證成功");
                     
                 } catch (Exception e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();
                 }
             }
         });
         
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  //釋放內存
         
       /*
      //子類對象的實例化
      		MyFileReader rf = new MyFileReader(message);
      	    FileWriter fw  = new FileWriter(securitymessage);
      	  FileWriter fw1  = new FileWriter(securitykey);
      		int c;
      		while((c=rf.read())!=-1)//讀取filte文件裏的內容直到讀完返回-1,並打印出讀取的內同。
      		{
      		   String encodedData = RSAUtils.publicEncrypt(String.valueOf(c), RSAUtils.getPublicKey(publicKey));
      		   fw.write(encodedData);
      		   fw.flush();
      		
      		}
      	//	 System.out.println("\r明文大小:\r\n" + str.getBytes().length+"B");
      //讀完後關閉打開的filte文檔。\
      		
      		fw1.write("公鑰:\n "+publicKey+"\n"+"私鑰:\n" + privateKey);
      		fw1.flush();
      		
      		
      		rf.close();
      		fw.close();
      		fw1.close();
    }   	

    JFrame frame = new JFrame("RSA加密解密");
    // Button名稱
    JButton button1 = new JButton("加密");
    JButton button2 = new JButton("解密");
    // JTextField名稱
    final JTextField content = new JTextField();
    content.setName("content");
    final JTextField pass = new JTextField();
    final JTextField dpass = new JTextField();

    // JLabel
    JLabel view = new JLabel("明文", JLabel.CENTER);
    view.setFont(new java.awt.Font("明文", 1, 15));//1代表粗細,15代表粗細
    view.setOpaque(true);
    view.setBackground(Color.GREEN);
    view.setForeground(Color.BLACK);

    // 畫布佈局
    JPanel contentPane = new JPanel();
    contentPane.add(button1);
    contentPane.add(button2);
    contentPane.add(content);
    contentPane.add(pass);
    contentPane.add(dpass);
    contentPane.add(view);
    frame.setContentPane(contentPane);
    contentPane.setLayout(null);

    // 大小設置
    view.setBounds(250, 0, 80, 30);
    content.setBounds(50, 0, 200, 30);
    pass.setBounds(50, 50, 200, 30);
    button1.setBounds(250, 50, 80, 30);
    dpass.setBounds(50, 100, 200, 30);
    button2.setBounds(250, 100, 80, 30);
    frame.setSize(400, 300);
    frame.setVisible(true);

    button1.addActionListener(
    		new ActionListener() 
    {

        @Override
        public void actionPerformed(ActionEvent e) 
        {
            // TODO Auto-generated method stub
            String str1 = content.getText().toString();
            try {
                pass.setText(publicEncrypt(str1,publicKey));
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace(); 
            }
        }
    }
    		);

    button2.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            String str2 = content.getText().toString();
            try {
                dpass.setText(str2);
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    });

}
       /* String str = "青青子衿\n" +
                "悠悠我心\n" +
                "但爲君故\n" +
                "沉吟至今\n" +
                "呦呦鹿鳴\n" +
                "食野之萍\n" +
                "我要拉屎";    */
       
  
  /*
   
        
        String encodedData = RSAUtils.publicEncrypt(str, RSAUtils.getPublicKey(publicKey));

        System.out.println("密文:\r\n" + encodedData);
        String decodedData = RSAUtils.privateDecrypt(encodedData, RSAUtils.getPrivateKey(privateKey));
        System.out.println("解密後文字: \r\n" + decodedData);

        

    
         
  
    	System.out.println("私鑰簽名——公鑰驗證\n");
        String str1= input.nextLine();
        System.out.println("\r明文:\r\n" + str1);
        System.out.println("\r明文大小:\r\n" + str1.getBytes().length+"B");
        String encodedData1 = RSAUtils.privateEncrypt(str1, RSAUtils.getPrivateKey(publicKey));
        System.out.println("密文:\r\n" + encodedData1);
        String decodedData1 = RSAUtils.publicDecrypt(encodedData1, RSAUtils.getPublicKey(privateKey));
        System.out.println("解密後文字: \r\n" + decodedData1);
  
      
    }
      
    */
    }
    
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章