Java-RSA加解密工具类(包含分段加解密)

import kafka.log.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

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.Arrays;
import java.util.HashMap;
import java.util.Map;

/**

  • @description: RSA加解密工具类

  • @fileName: RSAUtils.java

  • @author: Sure

  • @createAt: 2022/3/7 14:20

  • @updateBy: Sure

  • @remark:

  • */
    @Slf4j
    public class RsaUtils {

    /**

    • 加解密算法关键字
      */
      public static final String KEY_ALGORITHM = “RSA”;

    /**

    • 公钥关键字
      */
      private static final String PUBLIC_KEY = “RSAPublicKey”;

    /**

    • 私钥关键字
      */
      private static final String PRIVATE_KEY = “RSAPrivateKey”;

    /**

    • 默认编码
      */
      public static final String CHARSET = “UTF-8”;

    /**

    • 最大加密字节数,超出最大字节数需要分组加密
      */
      private static int MAX_ENCRYPT_BLOCK = 117;

    /**

    • 最大解密字节数,超出最大字节数需要分组解密
      */
      private static int MAX_DECRYPT_BLOCK = 256;

    /**

    • 解密
    • @param str 加密的base64串
    • @param privateKey base64私钥串
    • @return 解密后字符
      */
      public static String decrypt(String str, String privateKey) throws Exception {
      //64位解码加密后的字符串
      byte[] inputByte = Base64.decodeBase64(str.getBytes(CHARSET));
      //base64编码的私钥
      byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes(CHARSET));
      RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
      //RSA解密
      Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
      cipher.init(Cipher.DECRYPT_MODE, priKey);
      return new String(cipher.doFinal(inputByte), CHARSET);
      }

    /**

    • 加密
    • @param data 需要加密的数据
    • @param publicKey base64公钥串
    • @return 加密后的base64字符串
      */
      public static String encrypt(String data, String publicKey) throws Exception {
      // 取得公钥
      Key key = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes(CHARSET))));
      // 对数据加密
      Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
      cipher.init(Cipher.ENCRYPT_MODE, key);
      return new String(Base64.encodeBase64(cipher.doFinal(data.getBytes(CHARSET))), CHARSET);
      }

    /**

    • 获取base64私钥
    • @param keyMap 秘钥
    • @return 私钥
      */
      public static String getPrivateKeyStr(Map<String, Object> keyMap) {
      Key key = (Key) keyMap.get(PRIVATE_KEY);
      return Base64.encodeBase64String(key.getEncoded());
      }

    /**

    • 取得base64公钥
    • @param keyMap 秘钥
    • @return base64公钥
      */
      public static String getPublicKeyStr(Map<String, Object> keyMap) {
      Key key = (Key) keyMap.get(PUBLIC_KEY);
      return Base64.encodeBase64String(key.getEncoded());
      }

    /**

    • 初始化秘钥

    • @return 秘钥

    • @throws NoSuchAlgorithmException
      */
      public static Map<String, Object> initKey() throws NoSuchAlgorithmException {
      KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
      keyPairGen.initialize(2048);
      KeyPair keyPair = keyPairGen.generateKeyPair();
      //公钥
      RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
      //私钥
      RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
      Map<String, Object> keyMap = new HashMap<>(5);

      keyMap.put(PUBLIC_KEY, publicKey);
      keyMap.put(PRIVATE_KEY, privateKey);
      return keyMap;
      }

    /**

    • 分段解密
    • @param inputData 加密的base64字符串
    • @param privateKey base64的私钥
    • @return 解密后内容
    • @throws Exception
      */
      public static String decryptByShort(String inputData, String privateKey) throws Exception {
      //64位解码加密后的字符串
      byte[] inputBytes = Base64.decodeBase64(inputData.getBytes(CHARSET));
      //base64编码的私钥
      byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes(CHARSET));
      RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
      //RSA解密
      Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
      cipher.init(Cipher.DECRYPT_MODE, priKey);
      byte[] resultBytes = doFinalBySegment(inputBytes, cipher, MAX_DECRYPT_BLOCK);
      return new String(resultBytes, CHARSET);
      }

/**

  • 分段公钥加密

  • @param inputData 需要加密的字符串

  • @param publicKey 公钥

  • @return: 加密后的base64编码
    */
    public static String encryptByShort(String inputData, String publicKey) throws Exception {
    // 取得公钥
    Key key = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes(CHARSET))));
    // 对数据加密
    Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] resultBytes = doFinalBySegment(inputData.getBytes(CHARSET), cipher, MAX_ENCRYPT_BLOCK);
    return new String(Base64.encodeBase64(resultBytes), CHARSET);
    }

    /**

    • @Author: TheBigBlue
    • @Description: 分段加解密
    • @Date: 2019/9/24
    • @Return:
      **/
      private static byte[] doFinalBySegment(byte[] inputBytes, Cipher cipher, int maxLength) throws Exception {
      int inputLenth = inputBytes.length;
      log.info(“数据超出最大字节数进行分段加解密:maxLength={}, inputLength={}”, maxLength, inputLenth);
      // 标识
      int offSet = 0;
      byte[] cache;
      byte[] resultBytes = {};
      while (inputLenth - offSet > 0) {
      //超出最大字节数分组加密
      if (inputLenth - offSet > maxLength) {
      cache = cipher.doFinal(inputBytes, offSet, maxLength);
      offSet += maxLength;
      } else {
      //直接加密
      cache = cipher.doFinal(inputBytes, offSet, inputLenth - offSet);
      offSet = inputLenth;
      }
      resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
      System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
      }
      return resultBytes;
      }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值