https理解之RSA加密解密

最近複習https的加密原理,一時興起決定做個RSA加密解密的小例子,以加深理解:

package com.example;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class CreateSecrteKey {

    
    public class Keys {
        
    }
    public static final String KEY_ALGORITHM = "RSA";
    //public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    //獲得公鑰
    public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
        //獲得map中的公鑰對象 轉爲key對象
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        //byte[] publicKey = key.getEncoded();
        //編碼返回字符串
        return Base64.encodeBase64String(key.getEncoded());
    }

    //獲得私鑰
    public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
        //獲得map中的私鑰對象 轉爲key對象
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        //byte[] privateKey = key.getEncoded();
        //編碼返回字符串
        return Base64.encodeBase64String(key.getEncoded());
    }

   
    
    /** 
	 * RSA公鑰加密 
	 *  
	 * @param str 
	 *            加密字符串
	 * @param publicKey 
	 *            公鑰 
     * @return 
	 * @return 密文 
	 * @throws Exception 
	 *             加密過程中的異常信息 
	 */  
	public static String encrypt(String str, RSAPublicKey publicKey ) {
		//base64編碼的公鑰
			  
					Cipher cipher;
					try {
						cipher = Cipher.getInstance("RSA");
						cipher.init(Cipher.ENCRYPT_MODE, publicKey);
						String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
						return outStr;
					} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvalidKeyException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalBlockSizeException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (BadPaddingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (UnsupportedEncodingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
			 
				
				return "";
		 
		
	}

	/** 
	 * RSA私鑰解密
	 *  
	 * @param str 
	 *            加密字符串
	 * @param privateKey 
	 *            私鑰 
	 * @return 銘文
	 * @throws Exception 
	 *             解密過程中的異常信息 
	 */  
	public static String decrypt(String str, Key privateKey) throws Exception{
		//64位解碼加密後的字符串,解碼字符串
		byte[] meesageByte = Base64.decodeBase64(str.getBytes("UTF-8"));
	 
		//RSA解密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		byte [] decypted = cipher.doFinal(meesageByte);
		String outStr = new String(decypted,"UTF-8");
		return outStr;
 
	}

 
    
    //map對象中存放公私鑰
    public static Map<String, Object> initKey() throws Exception {
        //獲得對象 KeyPairGenerator 參數 RSA 1024個字節
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(1024);
        //通過對象 KeyPairGenerator 獲取對象KeyPair
        KeyPair keyPair = keyPairGen.generateKeyPair();
        
        //通過對象 KeyPair 獲取RSA公私鑰對象RSAPublicKey RSAPrivateKey
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        //公私鑰對象存入map中
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

    public static void main(String[] args) {
        Map<String, Object> keyMap;
        try {
            keyMap = initKey();
            String publicKey = getPublicKey(keyMap);
            System.out.println("公鑰:");
            System.out.println(publicKey);
            
            String privateKey = getPrivateKey(keyMap);
            System.out.println("私鑰:");
            System.out.println(privateKey);
            
            System.out.println("明文:");
            String message = "12點發動總攻,請提前作好準備。";
            System.out.println(message);
            
            String encodeMessage = encrypt(message, ((RSAPublicKey)keyMap.get(PUBLIC_KEY)));
            System.out.println("密文:");
            System.out.println(encodeMessage);
            
            String decodeMessage= decrypt(encodeMessage,((RSAPrivateKey)keyMap.get(PRIVATE_KEY)));
            System.out.println("解密:");
            System.out.println(new String(decodeMessage));
            
            
            
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

​

運行結果:

公鑰:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCg9LMXCyURFo+nzP2CgQgCyNzzprVQo3fpwlatJuV0V3BPR0hO6i4NLJ5VKEDdstTXS/lLxW262iVbBU1kZZE6tNgfImJ3f4bzYXnCaWs7LjtJCDwPgKJFRLR79JFQUngHDynsghdJN2eJ3luyf0IB6CsILUHLtl++jM4ppX/+RQIDAQAB
私鑰:
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKD0sxcLJREWj6fM/YKBCALI3POmtVCjd+nCVq0m5XRXcE9HSE7qLg0snlUoQN2y1NdL+UvFbbraJVsFTWRlkTq02B8iYnd/hvNhecJpazsuO0kIPA+AokVEtHv0kVBSeAcPKeyCF0k3Z4neW7J/QgHoKwgtQcu2X76Mzimlf/5FAgMBAAECgYEAlzImRYA/mpTB75PdlEkXOF5tSCgS7KQSUbEv8Mm4A5jbtG02nILZLaD7Pu1oOZny3CfPEAFuuXaQXrdVYvkR+Te9N/YUYmD3i3o3VTi2JwFGeTJL0Y9a3FKtMhbEASBxCnwOQG0mXpgYz96ctxczFKJ0noRJ232REkFjDr/UXKECQQD+IeHtuB4qctDl0QA2fF0P1u6krsyjY+bIUO2SuLJ/80Ytq+fM0d5YvpzSl2pU6AJnwoVxkDblJ3u5f+94ej9JAkEAoiOEdBl4bU0iqbBN3XCvFxrHD03BblOQxC41tKre+1C7nsCBDaY1RV1005fp40sIajOe73jHf1PD2kpQTYk7HQJAZ3zkxCl2H1MiPnQd4hJC03BzPhzwuJi2IlzSYi1Ug0ZODcszWfUc1obI1flTE8BnOlm8fcJ8mFS7zY6LtkQSAQJBAIbil1liqx37EsAqTMzQ5siI3Vts62OWH5QlgUZY9IIMytkp+vLY9+5J7lvtQIV3sXtwkGNWjljt3bxnIGEwrj0CQQDk8X7LbM9JdC8A7Ny2isqT5UsoB6i9W9XV8NTzhBCT3IIPBdGHFU8YDQuTYBnCp9fWdpjZ13WErhskOn3Ifyh+
明文:
12點發動總攻,請提前作好準備。
密文:
VUvpC2L484qhdMmNW7vr5jfXD5PRso+K1/dfM8S81Fr0BwePIG4oJolerMfMKKikkKAk/HncaK4oN+oeCH65DFb1chhpCXxvJIrkMWWgHgqko/s4JLt3wBN7U4pVcLjY5XU4WNhKa1vdUGcZHoaRVa0ziQiIQfSE3pAUN3zTrkk=
解密:
12點發動總攻,請提前作好準備。

上面用到了一個Base64的jar包,下載地址:https://commons.apache.org/proper/commons-codec/download_codec.cgi

 

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