xiejun
2024-11-01 80b6cbfc9c861469146318d0b3dd5f8b8b525b8a
Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/utils/RsaUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,381 @@
/*
 *      Copyright (c) 2018-2028, DreamLu All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: DreamLu å¢æ˜¥æ¢¦ (596392912@qq.com)
 */
package org.springblade.core.tool.utils;
import org.springframework.lang.Nullable;
import org.springframework.util.Base64Utils;
import org.springblade.core.tool.tuple.KeyPair;
import javax.crypto.Cipher;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import java.util.Objects;
/**
 * RSA加、解密工具
 *
 * <p>
 * 1. å…¬é’¥è´Ÿè´£åŠ å¯†ï¼Œç§é’¥è´Ÿè´£è§£å¯†ï¼›
 * 2. ç§é’¥è´Ÿè´£ç­¾åï¼Œå…¬é’¥è´Ÿè´£éªŒè¯ã€‚
 * </p>
 *
 * @author L.cm
 */
public class RsaUtil {
   /**
    * æ•°å­—签名,密钥算法
    */
   public static final String RSA_ALGORITHM = "RSA";
   public static final String RSA_PADDING = "RSA/ECB/PKCS1Padding";
   /**
    * èŽ·å– KeyPair
    *
    * @return KeyPair
    */
   public static KeyPair genKeyPair() {
      return genKeyPair(1024);
   }
   /**
    * èŽ·å– KeyPair
    *
    * @param keySize key size
    * @return KeyPair
    */
   public static KeyPair genKeyPair(int keySize) {
      try {
         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA_ALGORITHM);
         // å¯†é’¥ä½æ•°
         keyPairGen.initialize(keySize);
         // å¯†é’¥å¯¹
         return new KeyPair(keyPairGen.generateKeyPair());
      } catch (NoSuchAlgorithmException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * ç”ŸæˆRSA私钥
    *
    * @param modulus N特征值
    * @param exponent d特征值
    * @return {@link PrivateKey}
    */
   public static PrivateKey generatePrivateKey(String modulus, String exponent) {
      return generatePrivateKey(new BigInteger(modulus), new BigInteger(exponent));
   }
   /**
    * ç”ŸæˆRSA私钥
    *
    * @param modulus N特征值
    * @param exponent d特征值
    * @return {@link PrivateKey}
    */
   public static PrivateKey generatePrivateKey(BigInteger modulus, BigInteger exponent) {
      RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulus, exponent);
      try {
         KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
         return keyFactory.generatePrivate(keySpec);
      } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * ç”ŸæˆRSA公钥
    *
    * @param modulus N特征值
    * @param exponent e特征值
    * @return {@link PublicKey}
    */
   public static PublicKey generatePublicKey(String modulus, String exponent) {
      return generatePublicKey(new BigInteger(modulus), new BigInteger(exponent));
   }
   /**
    * ç”ŸæˆRSA公钥
    *
    * @param modulus N特征值
    * @param exponent e特征值
    * @return {@link PublicKey}
    */
   public static PublicKey generatePublicKey(BigInteger modulus, BigInteger exponent) {
      RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
      try {
         KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
         return keyFactory.generatePublic(keySpec);
      } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å¾—到公钥
    *
    * @param base64PubKey å¯†é’¥å­—符串(经过base64编码)
    * @return PublicKey
    */
   public static PublicKey getPublicKey(String base64PubKey) {
      Objects.requireNonNull(base64PubKey, "base64 public key is null.");
      byte[] keyBytes = Base64Utils.decodeFromString(base64PubKey);
      X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
      try {
         KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
         return keyFactory.generatePublic(keySpec);
      } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å¾—到公钥字符串
    *
    * @param base64PubKey å¯†é’¥å­—符串(经过base64编码)
    * @return PublicKey String
    */
   public static String getPublicKeyToBase64(String base64PubKey) {
      PublicKey publicKey = getPublicKey(base64PubKey);
      return getKeyString(publicKey);
   }
   /**
    * å¾—到私钥
    *
    * @param base64PriKey å¯†é’¥å­—符串(经过base64编码)
    * @return PrivateKey
    */
   public static PrivateKey getPrivateKey(String base64PriKey) {
      Objects.requireNonNull(base64PriKey, "base64 private key is null.");
      byte[] keyBytes = Base64Utils.decodeFromString(base64PriKey);
      PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
      try {
         KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
         return keyFactory.generatePrivate(keySpec);
      } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å¾—到密钥字符串(经过base64编码)
    *
    * @param key key
    * @return base 64 ç¼–码后的 key
    */
   public static String getKeyString(Key key) {
      return Base64Utils.encodeToString(key.getEncoded());
   }
   /**
    * å¾—到私钥 base64
    *
    * @param base64PriKey å¯†é’¥å­—符串(经过base64编码)
    * @return PrivateKey String
    */
   public static String getPrivateKeyToBase64(String base64PriKey) {
      PrivateKey privateKey = getPrivateKey(base64PriKey);
      return getKeyString(privateKey);
   }
   /**
    * å…±è¦åР坆
    *
    * @param base64PublicKey base64 çš„公钥
    * @param data            å¾…加密的内容
    * @return åŠ å¯†åŽçš„å†…å®¹
    */
   public static byte[] encrypt(String base64PublicKey, byte[] data) {
      return encrypt(getPublicKey(base64PublicKey), data);
   }
   /**
    * å…±è¦åР坆
    *
    * @param publicKey å…¬é’¥
    * @param data      å¾…加密的内容
    * @return åŠ å¯†åŽçš„å†…å®¹
    */
   public static byte[] encrypt(PublicKey publicKey, byte[] data) {
      return rsa(publicKey, data, Cipher.ENCRYPT_MODE);
   }
   /**
    * ç§é’¥åŠ å¯†ï¼Œç”¨äºŽ qpp å†…,公钥解密
    *
    * @param base64PrivateKey base64 çš„私钥
    * @param data             å¾…加密的内容
    * @return åŠ å¯†åŽçš„å†…å®¹
    */
   public static byte[] encryptByPrivateKey(String base64PrivateKey, byte[] data) {
      return encryptByPrivateKey(getPrivateKey(base64PrivateKey), data);
   }
   /**
    * ç§é’¥åŠ å¯†ï¼ŒåŠ å¯†æˆ base64 å­—符串,用于 qpp å†…,公钥解密
    *
    * @param base64PrivateKey base64 çš„私钥
    * @param data             å¾…加密的内容
    * @return åŠ å¯†åŽçš„å†…å®¹
    */
   public static String encryptByPrivateKeyToBase64(String base64PrivateKey, byte[] data) {
      return Base64Util.encodeToString(encryptByPrivateKey(base64PrivateKey, data));
   }
   /**
    * ç§é’¥åŠ å¯†ï¼Œç”¨äºŽ qpp å†…,公钥解密
    *
    * @param privateKey ç§é’¥
    * @param data       å¾…加密的内容
    * @return åŠ å¯†åŽçš„å†…å®¹
    */
   public static byte[] encryptByPrivateKey(PrivateKey privateKey, byte[] data) {
      return rsa(privateKey, data, Cipher.ENCRYPT_MODE);
   }
   /**
    * å…¬é’¥åР坆
    *
    * @param base64PublicKey base64 å…¬é’¥
    * @param data            å¾…加密的内容
    * @return åŠ å¯†åŽçš„å†…å®¹
    */
   @Nullable
   public static String encryptToBase64(String base64PublicKey, @Nullable String data) {
      if (StringUtil.isBlank(data)) {
         return null;
      }
      return Base64Utils.encodeToString(encrypt(base64PublicKey, data.getBytes(Charsets.UTF_8)));
   }
   /**
    * è§£å¯†
    *
    * @param base64PrivateKey base64 ç§é’¥
    * @param data             æ•°æ®
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   public static byte[] decrypt(String base64PrivateKey, byte[] data) {
      return decrypt(getPrivateKey(base64PrivateKey), data);
   }
   /**
    * è§£å¯†
    *
    * @param base64publicKey base64 å…¬é’¥
    * @param data            æ•°æ®
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   public static byte[] decryptByPublicKey(String base64publicKey, byte[] data) {
      return decryptByPublicKey(getPublicKey(base64publicKey), data);
   }
   /**
    * è§£å¯†
    *
    * @param privateKey privateKey
    * @param data       æ•°æ®
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   public static byte[] decrypt(PrivateKey privateKey, byte[] data) {
      return rsa(privateKey, data, Cipher.DECRYPT_MODE);
   }
   /**
    * è§£å¯†
    *
    * @param publicKey PublicKey
    * @param data      æ•°æ®
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   public static byte[] decryptByPublicKey(PublicKey publicKey, byte[] data) {
      return rsa(publicKey, data, Cipher.DECRYPT_MODE);
   }
   /**
    * rsa åŠ ã€è§£å¯†
    *
    * @param key  key
    * @param data æ•°æ®
    * @param mode æ¨¡å¼
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   private static byte[] rsa(Key key, byte[] data, int mode) {
      try {
         Cipher cipher = Cipher.getInstance(RSA_PADDING);
         cipher.init(mode, key);
         return cipher.doFinal(data);
      } catch (Exception e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * base64 æ•°æ®è§£å¯†
    *
    * @param base64PublicKey base64 å…¬é’¥
    * @param base64Data      base64数据
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   public static byte[] decryptByPublicKeyFromBase64(String base64PublicKey, byte[] base64Data) {
      return decryptByPublicKey(getPublicKey(base64PublicKey), base64Data);
   }
   /**
    * base64 æ•°æ®è§£å¯†
    *
    * @param base64PrivateKey base64 ç§é’¥
    * @param base64Data       base64数据
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   @Nullable
   public static String decryptFromBase64(String base64PrivateKey, @Nullable String base64Data) {
      if (StringUtil.isBlank(base64Data)) {
         return null;
      }
      return new String(decrypt(base64PrivateKey, Base64Utils.decodeFromString(base64Data)), Charsets.UTF_8);
   }
   /**
    * base64 æ•°æ®è§£å¯†
    *
    * @param base64PrivateKey base64 ç§é’¥
    * @param base64Data       base64数据
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   public static byte[] decryptFromBase64(String base64PrivateKey, byte[] base64Data) {
      return decrypt(base64PrivateKey, Base64Utils.decode(base64Data));
   }
   /**
    * base64 æ•°æ®è§£å¯†
    *
    * @param base64PublicKey base64 å…¬é’¥
    * @param base64Data      base64数据
    * @return è§£å¯†åŽçš„æ•°æ®
    */
   @Nullable
   public static String decryptByPublicKeyFromBase64(String base64PublicKey, @Nullable String base64Data) {
      if (StringUtil.isBlank(base64Data)) {
         return null;
      }
      return new String(decryptByPublicKeyFromBase64(base64PublicKey, Base64Utils.decodeFromString(base64Data)), Charsets.UTF_8);
   }
}