最近複習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