Java---RSA私钥加密解密,公钥加密解密--方法_java rsa公钥解密_系子818的博客-程序员宅基地

技术标签: spring boot  java  java-ee  开发语言  


package com.my.demo.utils;
 
import com.my.demo.common.Constants;
import com.my.experiment.exception.OptException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;
 
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
 
 
 
@Component
public class RsaUtil {

/**
     * 日志记录器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(RsaUtil .class);

    private static final String KEY_ALGORITHM = "RSA";
    private static final String PK = Constants.getPublicKey();
    private static final String SK = Constants.getPrivateKey();
 
    /**
     * 使用RSA公钥加密
     */
 
    public static String encryptByPublicKey(String str) {
        return Base64.encodeBase64String(getMaxResultEncrypt(str, getPublicKey(Cipher.ENCRYPT_MODE)));
    }
    /**
     * 使用公钥解密
     */
    public static String decryptByPublicKey(String data) {
        try {
            return new String(getMaxResultDecrypt(data, getPublicKey(Cipher.DECRYPT_MODE)));
        }catch (Exception e){
            throw new OptException("解密失败|"+e.getMessage());
        }
    }
    /**
     * 使用RSA私钥解密
     *
     * @param str 加密字符串
     */
    public static String decryptByPrivateKey(String str) {
        return new String(getMaxResultDecrypt(str, getPrivateKey(Cipher.DECRYPT_MODE)));
    }
 
    /**
     * 使用RSA私钥加密
     * @param data       加密数据
     */
    public static String encryptByPrivateKey(String data) {
        try {
            return Base64.encodeBase64String(getMaxResultEncrypt(data, getPrivateKey(Cipher.ENCRYPT_MODE)));
        } catch (Exception e) {
            throw new OptException("加密失败|"+e.getMessage());
        }
    }
    /**
     * 当长度过长的时候,需要分割后加密 117个字节
     */
    private static byte[] getMaxResultEncrypt(String str, Cipher cipher){
        try {
            byte[] inputArray = str.getBytes(StandardCharsets.UTF_8.name());
            int inputLength = inputArray.length;
            // 最大加密字节数,超出最大字节数需要分组加密
            int maxEncryptBlock = 117;
            // 标识
            int offSet = 0;
            byte[] resultBytes = {};
            byte[] cache;
            while (inputLength - offSet > 0) {
                if (inputLength - offSet > maxEncryptBlock) {
                    cache = cipher.doFinal(inputArray, offSet, maxEncryptBlock);
                    offSet += maxEncryptBlock;
                } else {
                    cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
                    offSet = inputLength;
                }
                resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
                System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
            }
            return resultBytes;
        }catch (Exception e){
            e.printStackTrace();
            throw new OptException("加密处理失败,"+e.getMessage());
        }
    }
 
    /**
     * 当长度过长的时候,需要分割后解密 128个字节
     */
    private static byte[] getMaxResultDecrypt(String str, Cipher cipher) {
        try {
            byte[] inputArray = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8.name()));
            int inputLength = inputArray.length;
            // 最大解密字节数,超出最大字节数需要分组加密
            int maxEncryptBlock = 128;
            int offSet = 0;
            byte[] resultBytes = {};
            byte[] cache;
            while (inputLength - offSet > 0) {
                if (inputLength - offSet > maxEncryptBlock) {
                    cache = cipher.doFinal(inputArray, offSet, maxEncryptBlock);
                    offSet += maxEncryptBlock;
                } else {
                    cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
                    offSet = inputLength;
                }
                resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
                System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
            }
            return resultBytes;
        }catch (Exception e){
            e.printStackTrace();
            throw new OptException("解密数据处理异常,"+e.getMessage());
        }
    }
    /**
     * 根据加解密类型处理公钥
     *
     */
    public static Cipher getPublicKey(int mode) {
        try {
            String publicKey = formatString(PK);
            byte[] decoded = Base64.decodeBase64(publicKey);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decoded);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey key = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(mode, key);
            return cipher;
        } catch (Exception e) {
            throw new OptException("转换公钥异常====>>" + e.getMessage());
        }
    }
 
    /**
     * 根据加解密类型处理私钥
     */
    public static Cipher getPrivateKey(int mode) {
        try {
            //mode 加解密模式 ENCRYPT_MODE = 1  DECRYPT_MODE = 2
            String privateKey = formatString(SK);
            byte[] decoded = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decoded);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey key = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(mode, key);
            return cipher;
        } catch (Exception e) {
            throw new OptException("转换私钥异常====>>" + e.getMessage());
        }
    }
    public static String formatString(String source) {
        if (source == null) {
            return null;
        }
        return source.replace("\\r", "").replace("\\n", "").trim().replace(" ","");
    }
    public static void main(String[] args) throws Exception {
        String xxStr = "的发挥很大的22@@@";
        //加密
        String bytes1 = RsaUtil.encryptByPrivateKey(xxStr);
        String bytes2 = RsaUtil.encryptByPublicKey(xxStr);
        log.info("公钥加密2:{}",bytes2);
        log.info("私钥加密1:{}",bytes1);
 
        //解密
        log.info("私钥解密密2:{}",RsaUtil.decryptByPrivateKey(bytes2));
        log.info("公钥解密密1:{}",RsaUtil.decryptByPublicKey(bytes1));
 
    }
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_57085190/article/details/124703637

智能推荐

【Qt笔记】使用 SAX 处理 XML-程序员宅基地

2019独角兽企业重金招聘Python工程师标准>>> ...

Qgis Python开发环境配置——第二弹_qgis python error-程序员宅基地

在之前一篇文章介绍了用Qgis2.14搭建python独立开发环境,至那次之后使用一直没什么问题,但是后来才发现一个比较坑的事情,就是原来安装的Qgis3.01不能用了,看来不能同时用两个版本,之前在3版本下写的python脚本在2.14下面运行出错,于是还是考虑用Qgis3.01来搭建python独立环境,上次没时间试试,昨天试了一下,大体上没什么问题,但是还是有个坑,但不管先记录下来,后续再说..._qgis python error

c语言xyz最小值,有关问题XYZ的10种语言解决方案(一)之C语言篇-程序员宅基地

问题XYZ的10种语言解决方案(一)之C语言篇写这篇,或者这个系列的无聊博客文章完全是由于昨晚没事瞎想想到的,本来是在思考《Learn you a Hashkell for Great Good》中快速排序的Haskell实现代码,突然想到用其它语言来写写,然后做做对比其实很有意思,于是决定今天起来就做这件事情,由于是在想快速排序时想到的,因此也就将快速排序的实现作为第一篇吧。在这个系列的博客文章..._1/xyz最小值

面试基础之Hashmap21问_hash21-程序员宅基地

1:HashMap 的数据结构?A:哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点。当链表长度超过 8 时,链表转换为红黑树。transient Node<K,V>[] table;2:HashMap 的工作原理?HashMap 底层是 hash 数组和单向链表实现,数组中的每个元素都是链表,由 Node 内部类(实现 Map.Entry<K,V>接口)实现,HashMap 通过 put & get 方法存储和获取。存储对象时,将 K/V 键值传_hash21

Java密码学原型算法实现——第一部分:标准Hash算法_java 密码学 hash库-程序员宅基地

虽然C在密码学中有不可替代的优势:速度快,但是,Java的可移植性使得开发人员可以很快地将代码移植到各个平台,这比C实现要方便的多。尤其是Android平台的出现,Java的应用也就越来越广。因此,我本人在密码学研究过程中实际上也在逐渐使用和封装一些知名的Java密码学库,主要是方便自己使用。第一部分的实现是标准Hash算法。这一实现使用的是Java JDK,但是使用了Bouncy Castle的工具库实现Byte和String的一些转换。_java 密码学 hash库

Linux查看jquery版本号,npm 如何查看一个包的版本信息?-程序员宅基地

有了npm 我们能够简单的一段代码就下载我们需要的包,但是包是不断更新的,所以我们要关注包的版本信息;现在,假设我们需要 jquery ,但是jquery现在有很多版本,我们如何通过npm查看呢?查看远程仓库相关版本要知道,现在的jquery包在npm服务器的上,我们使用下面的命令查看:第一种方式:使用npm view jquery versions这种方式可以查看npm服务器上所有的jquer..._linux查看查看jquery版本

随便推点

基于线程池的http服务器-程序员宅基地

前端时间,用线程池做了一个http服务器,专门处理get请求,基于socket编程,主要是自己想对操作系统级的编程比较感兴趣。好了,贴出代码,供大家参考: public static void main(String[] args) { // TODO Auto-generated method stub try{ ServerSocket serve_基于线程池的http服务器

英特尔cpu发布时间表_2014英特尔处理器发布时间表-程序员宅基地

类型:显卡驱动大小:40.8M语言:中文 评分:5.0标签:立即下载2014英特尔处理器发布时间表一览,感兴趣的可以和西西一起来看看!作为x86处理器老大英特尔在2014年会有哪些走向,可能不少人都相当好奇,我们就简单利用一张图来让大家了解。今年,英特尔发布的处理器产品相当多,我们就依照时间表来了解今年有哪些产品。首先在2月份,英特尔将向Server服务器市场发布Xeon E7-8800/4800..._英特尔cpu发布时间表

c语言新建文件怎么弹出HTML,c++创建html文件_Outtttta的博客-程序员宅基地

c++创建html文件其实就是创建普通文件, CreateFile() 和WriteFile. 然后用ShellExcuteEx()来打开就行了(会自动调用IE).HANDLE handle;handle=CreateFile(L"\\windows\\google.html",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NUL..._c语言生成html

php调用汇率,php 实时汇率接口_天王不在家的博客-程序员宅基地

​function getExchangeRate($from_Currency,$to_Currency){$amount = urlencode($amount);$from_Currency = urlencode($from_Currency);$to_Currency = urlencode($to_Currency);$url = "download.finance.yahoo.com...

Vue3 触发组件选项(自定义事件)_vue3触发事件-程序员宅基地

触发组件选项(自定义事件)事件名事件名提供了自动的大小写转换,在子组件中使用驼峰命名的方法触发一个事件,父组件中通过-的形式 书写触发对应的方法名 this.$emit('myEvent'); <parent-com @my-event="myEvent" ></parent-com>定义自定义事件可以通过 emits 选项在组件上定义已发出的事件。当在 emits 选项中定义了原生事件 (如 click) 时,将使用组件中的事件替代原生事件侦听器_vue3触发事件