java RSAUtils 加密工具類操作
阿新 • • 發佈:2020-08-19
1.RSA加密演算法是一種非對稱加密演算法。在公開金鑰加密和電子商業中RSA被廣泛使用。RSA公開金鑰密碼體制。所謂的公開金鑰密碼體制就是使用不同的加密金鑰與解密金鑰,是一種“由已知加密金鑰推匯出解密金鑰在計算上是不可行的”密碼體制。在公開金鑰密碼體制中,加密金鑰(即公開金鑰)PK是公開資訊,而解密金鑰(即祕密金鑰)SK是需要保密的。加密演算法E和解密演算法D也都是公開的。雖然解密金鑰SK是由公開金鑰PK決定的,但卻不能根據PK計算出SK。
2.本工具類涉及到BASE64編碼,所以先展示出BASE64Utils:
package com.example.springboottest.common.util; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.security.MessageDigest; /** * BASE64的加解密 * @author Neo * @date 2018-4-15 22:21:51 * */ @SuppressWarnings("restriction") public class Base64Utils { public static final String KEY_SHA = "SHA"; public static final String KEY_MD5 = "MD5"; /** * BASE64解密 * * @param key * @return * @throws Exception */ public static byte[] decryptBASE64(String key) throws Exception { return (new BASE64Decoder()).decodeBuffer(key); } /** * BASE64加密 * * @param key * @return * @throws Exception */ public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); } /** * MD5加密 * * @param data * @return * @throws Exception */ public static byte[] encryptMD5(byte[] data) throws Exception { MessageDigest md5 = MessageDigest.getInstance(KEY_MD5); md5.update(data); return md5.digest(); } /** * SHA加密 * * @param data * @return * @throws Exception */ public static byte[] encryptSHA(byte[] data) throws Exception { MessageDigest sha = MessageDigest.getInstance(KEY_SHA); sha.update(data); return sha.digest(); } }
3.然後我們展示RSAUtils:
package com.example.springboottest.common.util; import javax.crypto.Cipher; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * RSA安全編碼元件 * * @version 1.0 * @desc 公鑰和私鑰存放在properties檔案的時候每行的末尾加上“\r\n\” <br/> * “\r\n” 起到換行的作用,最後的“\”在properties在裡表示連線 * * @author Neo * @date 2018-4-15 22:23:19 * @since 1.0 */ public class RSAUtils extends Base64Utils { 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"; /** * 用私鑰對資訊生成數字簽名 * * @param data 加密資料 * @param privateKey 私鑰 * @return * @throws Exception */ public static String sign(String data,String privateKey) throws Exception { return sign(data.getBytes(),privateKey); } /** * 用私鑰對資訊生成數字簽名 * * @param data 加密資料 * @param privateKey 私鑰 * @return * @throws Exception */ public static String sign(byte[] data,String privateKey) throws Exception { // 解密由base64編碼的私鑰 byte[] keyBytes = decryptBASE64(privateKey); // 構造PKCS8EncodedKeySpec物件 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密演算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私鑰匙物件 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私鑰對資訊生成數字簽名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return encryptBASE64(signature.sign()); } /** * 校驗數字簽名 * * @param data 加密資料 * @param publicKey 公鑰 * @param sign 數字簽名 * @return 校驗成功返回true 失敗返回false * @throws Exception */ public static boolean verify(String data,String publicKey,String sign) throws Exception { return verify(data.getBytes(),publicKey,sign); } /** * 校驗數字簽名 * * @param data 加密資料 * @param publicKey 公鑰 * @param sign 數字簽名 * @return 校驗成功返回true 失敗返回false * @throws Exception */ public static boolean verify(byte[] data,String sign) throws Exception { // 解密由base64編碼的公鑰 byte[] keyBytes = decryptBASE64(publicKey); // 構造X509EncodedKeySpec物件 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密演算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公鑰匙物件 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(data); // 驗證簽名是否正常 return signature.verify(decryptBASE64(sign)); } /** * 解密<br> * 用私鑰解密 * * @param data * @param key * @return * @throws Exception */ public static String decryptByPrivateKey(String data,String key) throws Exception { return new String(decryptByPrivateKey(Base64Utils.decryptBASE64(data),key)); } /** * 解密<br> * 用私鑰解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data,String key) throws Exception { // 對金鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 對資料解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE,privateKey); return cipher.doFinal(data); } /** * 解密<br> * 用私鑰解密 * * @param data * @param key * @return * @throws Exception */ public static String decryptByPublicKey(String data,String key) throws Exception { return new String(decryptByPublicKey(Base64Utils.decryptBASE64(data),key)); } /** * 解密<br> * 用私鑰解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data,String key) throws Exception { // 對金鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 對資料解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE,publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用公鑰加密 * * @param data * @param key * @return * @throws Exception */ public static String encryptByPublicKey(String data,String key) throws Exception { return Base64Utils.encryptBASE64(encryptByPublicKey(data.getBytes(),key)); } /** * 加密<br> * 用公鑰加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data,String key) throws Exception { // 對公鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 對資料加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE,publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用私鑰加密 * * @param data * @param key * @return * @throws Exception */ public static String encryptByPrivateKey(String data,String key) throws Exception { return Base64Utils.encryptBASE64(encryptByPrivateKey(data.getBytes(),key)); } /** * 加密<br> * 用私鑰加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data,String key) throws Exception { // 對金鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 對資料加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE,privateKey); return cipher.doFinal(data); } /** * 取得私鑰 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String,Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公鑰 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map<String,Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化金鑰 * * @return * @throws Exception */ public static Map<String,Object> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); // 公鑰 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私鑰 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 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) { try { Map<String,Object> map = RSAUtils.initKey(); String publicKey = RSAUtils.getPublicKey(map); String privateKey = RSAUtils.getPrivateKey(map); System.out.println("公鑰:" + publicKey); System.out.println("私鑰:" + privateKey); String data = "Java是世界上最好的程式語言"; String encryptData = RSAUtils.encryptByPublicKey(data,publicKey); System.out.println("加密後:" + encryptData); String decryptData = RSAUtils.decryptByPrivateKey(encryptData,privateKey); System.out.println("解密後:" + decryptData); } catch (Exception e) { e.printStackTrace(); } } }
4.最後展示測試結果:
補充知識:java使用RSA生成公鑰和私鑰,並進行加解密
廢話不多說,上程式碼:
import javax.crypto.Cipher; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * Java RSA 加密工具類 */ public class RSAUtils { /** * 金鑰長度 於原文長度對應 以及越長速度越慢 */ private final static int KEY_SIZE = 1024; /** * 用於封裝隨機產生的公鑰與私鑰 */ private static Map<Integer,String> keyMap = new HashMap<Integer,String>(); /** * 隨機生成金鑰對 * @throws Exception */ public static void genKeyPair() throws Exception { // KeyPairGenerator類用於生成公鑰和私鑰對,基於RSA演算法生成物件 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); // 初始化金鑰對生成器 keyPairGen.initialize(KEY_SIZE,new SecureRandom()); // 生成一個金鑰對,儲存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); // 得到私鑰 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到公鑰 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); String publicKeyString = encryptBASE64(publicKey.getEncoded()); // 得到私鑰字串 String privateKeyString = encryptBASE64(privateKey.getEncoded()); // 將公鑰和私鑰儲存到Map //0表示公鑰 keyMap.put(0,publicKeyString); //1表示私鑰 keyMap.put(1,privateKeyString); } //編碼返回字串 public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); } //解碼返回byte public static byte[] decryptBASE64(String key) throws Exception { return (new BASE64Decoder()).decodeBuffer(key); } /** * RSA公鑰加密 * * @param str 加密字串 * @param publicKey 公鑰 * @return 密文 * @throws Exception 加密過程中的異常資訊 */ public static String encrypt(String str,String publicKey) throws Exception { //base64編碼的公鑰 byte[] decoded = decryptBASE64(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); //RSA加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE,pubKey); String outStr = encryptBASE64(cipher.doFinal(str.getBytes("UTF-8"))); return outStr; } /** * RSA私鑰解密 * * @param str 加密字串 * @param privateKey 私鑰 * @return 明文 * @throws Exception 解密過程中的異常資訊 */ public static String decrypt(String str,String privateKey) throws Exception { //64位解碼加密後的字串 byte[] inputByte = decryptBASE64(str); //base64編碼的私鑰 byte[] decoded = decryptBASE64(privateKey); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); //RSA解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE,priKey); String outStr = new String(cipher.doFinal(inputByte)); return outStr; } public static void main(String[] args) throws Exception { long temp = System.currentTimeMillis(); //生成公鑰和私鑰 genKeyPair(); //加密字串 System.out.println("公鑰:" + keyMap.get(0)); System.out.println("私鑰:" + keyMap.get(1)); System.out.println("生成金鑰消耗時間:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒"); String message = "RSA測試aaa"; System.out.println("原文:" + message); temp = System.currentTimeMillis(); String messageEn = encrypt(message,keyMap.get(0)); System.out.println("密文:" + messageEn); System.out.println("加密消耗時間:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒"); temp = System.currentTimeMillis(); String messageDe = decrypt(messageEn,keyMap.get(1)); System.out.println("解密:" + messageDe); System.out.println("解密消耗時間:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒"); } }
以上這篇java RSAUtils 加密工具類操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。