使用hutool提供的RSA工具实现RSA加密解密算法

RSAUtils代码
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import org.springframework.util.Base64Utils;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * RSA加密解密
 * @version 2022-11-03
 * @since V0.1.0
 */
public class RSAUtils {

    /**
     * 类型
     */
    public static final String ENCRYPT_TYPE_RSA = "RSA";

    /**
     * 公钥
     */
    public static final String PUBLIC_KEY = "RSAPublicKey";

    /**
     * 私钥
     */
    public static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 键值对过期时间 30秒
     */
    static final Long cacheTime =  30 * 1000L;


    /**
     * 获取公钥私钥对
     * @return
     * @throws Exception
     */
    public static Map<String, String> generateKeyPair() throws Exception {
        KeyPair pair = SecureUtil.generateKeyPair(ENCRYPT_TYPE_RSA);
        PrivateKey privateKey = pair.getPrivate();
        PublicKey publicKey = pair.getPublic();
        // 获取 公钥和私钥 的 编码格式(通过该 编码格式 可以反过来 生成公钥和私钥对象)
        byte[] pubEncBytes = publicKey.getEncoded();
        byte[] priEncBytes = privateKey.getEncoded();
        // 把 公钥和私钥 的 编码格式 转换为 Base64文本 方便保存
        String pubEncBase64 = Base64.getEncoder().encodeToString(pubEncBytes);
        String priEncBase64 = Base64.getEncoder().encodeToString(priEncBytes);
        Map<String, String> map = new HashMap<String, String>(2);
        map.put(PUBLIC_KEY, pubEncBase64);
        map.put(PRIVATE_KEY, priEncBase64);
        // 将公钥和私钥放进集合存储
        ConcurrentHashMapUtil.setCache(pubEncBase64, priEncBase64, cacheTime);
        return map;
    }

    /**
     * 加密
     * @param input 加密前的值
     * @param publicKeyBase64  公钥
     * @return
     * @throws Exception
     */
    public static String encrypt(String input, String publicKeyBase64)
            throws Exception {
        RSA rsa = new RSA(null, publicKeyBase64);
        //公钥加密
        return rsa.encryptBase64(input, KeyType.PublicKey);
    }

    /**
     * 解密
     * @param input  加密后的值
     * @param publicKeyBase64  公钥
     * @return
     * @throws Exception
     */
    public static String decrypt(String input, String publicKeyBase64)
            throws Exception {
        // 通过公钥获取私钥
        RSA rsa = new RSA(ConcurrentHashMapUtil.getCache(publicKeyBase64).toString(), null);
        // 解密
        byte[] s = rsa.decrypt(Base64Utils.decode(input.getBytes(StandardCharsets.UTF_8)), KeyType.PrivateKey);
        // 删除公钥和密钥对象
        ConcurrentHashMapUtil.deleteCache(publicKeyBase64);
        return new String(s);
    }


    /**
     * 测试
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Map<String, String> map = generateKeyPair();
        String encrypt = encrypt("测试", map.get(PUBLIC_KEY));
        System.out.println(encrypt);
        String public_key = map.get(PUBLIC_KEY);
        String private_key = map.get(PRIVATE_KEY);
        System.out.println(public_key);
        System.out.println(private_key);
    }


}
ConcurrentHashMapUtil代码(防止获取了秘钥key不消费)

/**
 * 键值对缓存工具
 * @version 2022-11-03
 * @since V0.1.0
 **/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapUtil {

    /**
     *
     * */
    private static Logger LOGGER = LoggerFactory.getLogger(ConcurrentHashMapUtil.class);

    /**
     * 缓存最大个数
     */
    private static final Integer CACHE_MAX_NUMBER = 1000;

    /**
     * 当前缓存个数
     */
    private static Integer CURRENT_SIZE = 0;

    /**
     * 时间三十分钟
     */
    static final Long ONE_MINUTE = 30 * 60 * 1000L;

    /**
     * 缓存对象
     */
    private static final Map<String, CacheObj> CACHE_OBJECT_MAP = new ConcurrentHashMap<>();

    /**
     * 这个记录了缓存使用的最后一次的记录,最近使用的在最前面
     */
    private static final List<String> CACHE_USE_LOG_LIST = new LinkedList<>();

    /**
     * 清理过期缓存是否在运行
     */
    private static volatile Boolean CLEAN_THREAD_IS_RUN = false;

    /**
     * 设置缓存
     */
    public static void setCache(String cacheKey, Object cacheValue, long cacheTime) {
        Long ttlTime = null;
        if (cacheTime <= 0L) {
            if (cacheTime == -1L) {
                ttlTime = -1L;
            } else {
                return;
            }
        }
        checkSize();
        saveCacheUseLog(cacheKey);
        CURRENT_SIZE = CURRENT_SIZE + 1;
        if (ttlTime == null) {
            ttlTime = System.currentTimeMillis() + cacheTime;
        }
        CacheObj cacheObj = new CacheObj(cacheValue, ttlTime);
        CACHE_OBJECT_MAP.put(cacheKey, cacheObj);
        LOGGER.info("have set key :" + cacheKey);
    }

    /**
     * 设置缓存
     */
    public static void setCache(String cacheKey, Object cacheValue) {
        setCache(cacheKey, cacheValue, -1L);
    }

    /**
     * 获取缓存
     */
    public static Object getCache(String cacheKey) {
        startCleanThread();
        if (checkCache(cacheKey)) {
            saveCacheUseLog(cacheKey);
            return CACHE_OBJECT_MAP.get(cacheKey).getCacheValue();
        }
        return null;
    }

    public static boolean isExist(String cacheKey) {
        return checkCache(cacheKey);
    }

    /**
     * 删除所有缓存
     */
    public static void clear() {
        LOGGER.info("have clean all key !");
        CACHE_OBJECT_MAP.clear();
        CURRENT_SIZE = 0;
    }

    /**
     * 删除某个缓存
     */
    public static void deleteCache(String cacheKey) {
        Object cacheValue = CACHE_OBJECT_MAP.remove(cacheKey);
        if (cacheValue != null) {
            LOGGER.info("have delete key :" + cacheKey);
            CURRENT_SIZE = CURRENT_SIZE - 1;
        }
    }

    /**
     * 判断缓存在不在,过没过期
     */
    private static boolean checkCache(String cacheKey) {
        CacheObj cacheObj = CACHE_OBJECT_MAP.get(cacheKey);
        if (cacheObj == null) {
            return false;
        }
        if (cacheObj.getTtlTime() == -1L) {
            return true;
        }
        if (cacheObj.getTtlTime() < System.currentTimeMillis()) {
            deleteCache(cacheKey);
            return false;
        }
        return true;
    }

    /**
     * 删除最近最久未使用的缓存
     */
    private static void deleteLRU() {
        LOGGER.info("delete Least recently used run!");
        String cacheKey = null;
        synchronized (CACHE_USE_LOG_LIST) {
            if (CACHE_USE_LOG_LIST.size() >= CACHE_MAX_NUMBER - 10) {
                cacheKey = CACHE_USE_LOG_LIST.remove(CACHE_USE_LOG_LIST.size() - 1);
            }
        }
        if (cacheKey != null) {
            deleteCache(cacheKey);
        }
    }

    /**
     * 删除过期的缓存
     */
    static void deleteTimeOut() {
        LOGGER.info("delete time out run!");
        List<String> deleteKeyList = new LinkedList<>();
        for(Map.Entry<String, CacheObj> entry : CACHE_OBJECT_MAP.entrySet()) {
            if (entry.getValue().getTtlTime() < System.currentTimeMillis() && entry.getValue().getTtlTime() != -1L) {
                deleteKeyList.add(entry.getKey());
            }
        }

        for (String deleteKey : deleteKeyList) {
            deleteCache(deleteKey);
        }
        LOGGER.info("delete cache count is :" + deleteKeyList.size());

    }

    /**
     * 检查大小
     * 当当前大小如果已经达到最大大小
     * 首先删除过期缓存,如果过期缓存删除过后还是达到最大缓存数目
     * 删除最久未使用缓存
     */
    private static void checkSize() {
        if (CURRENT_SIZE >= CACHE_MAX_NUMBER) {
            deleteTimeOut();
        }
        if (CURRENT_SIZE >= CACHE_MAX_NUMBER) {
            deleteLRU();
        }
    }

    /**
     * 保存缓存的使用记录
     */
    private static synchronized void saveCacheUseLog(String cacheKey) {
        synchronized (CACHE_USE_LOG_LIST) {
            CACHE_USE_LOG_LIST.remove(cacheKey);
            CACHE_USE_LOG_LIST.add(0,cacheKey);
        }
    }

    /**
     * 设置清理线程的运行状态为正在运行
     */
    static void setCleanThreadRun() {
        CLEAN_THREAD_IS_RUN = true;
    }

    /**
     * 开启清理过期缓存的线程
     */
    private static void startCleanThread() {
        if (!CLEAN_THREAD_IS_RUN) {
            CleanTimeOutThread cleanTimeOutThread = new CleanTimeOutThread();
            Thread thread = new Thread(cleanTimeOutThread);
            //设置为后台守护线程
            thread.setDaemon(true);
            thread.start();
        }
    }

}

class CacheObj {
    /**
     * 缓存对象
     */
    private Object CacheValue;
    /**
     * 缓存过期时间
     */
    private Long ttlTime;

    CacheObj(Object cacheValue, Long ttlTime) {
        CacheValue = cacheValue;
        this.ttlTime = ttlTime;
    }

    Object getCacheValue() {
        return CacheValue;
    }

    Long getTtlTime() {
        return ttlTime;
    }

    @Override
    public String toString() {
        return "CacheObj {" +
                "CacheValue = " + CacheValue +
                ", ttlTime = " + ttlTime +
                '}';
    }
}

/**
 * 每三十分钟清理一次过期缓存
 */
class CleanTimeOutThread implements Runnable{

    @Override
    public void run() {
        ConcurrentHashMapUtil.setCleanThreadRun();
        while (true) {
            System.out.println("clean thread run ");
            ConcurrentHashMapUtil.deleteTimeOut();
            try {
                Thread.sleep(ConcurrentHashMapUtil.ONE_MINUTE);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值