Java--RSA非对称加密的实现(使用java.security.KeyPair)

news2024/9/20 10:56:59

文章目录

        • 前言
        • 实现步骤
        • 测试结果

前言
  • 非对称加密是指使用不同的两个密钥进行加密和解密的一种加密算法,调用方用使用服务方提供的公钥进行加密,服务方使用自己的私钥进行解密。RSA算法是目前使用最广泛的公钥密码算法。
  • Java提供了KeyPairGenerator类要生成公钥和私钥密钥对(KeyPair),本文将提供两个接口,模拟公钥加密字符串和私钥解密字符串的过程。
实现步骤
  1. 创建RsaService,该类提供以下方法:

    genKeyPair(): 初始化密钥对,并将生成的密钥对存入Redis
    getPublicKey()/getPrivateKey(): 提供获取公钥和私钥的方法
    encrypt(String password)/decrypt(String password): 提供加密和解密的方法,供其他类调用

    @Service
    public class RsaService { 
        @Autowired
        private RedisOperation redisOperation;
        /**
        * 初始化随机生成密钥对
        */
        @PostConstruct
        public void genKeyPair() throws NoSuchAlgorithmException {
            // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            // 初始化密钥对生成器,密钥大小为96-1024位
            // 这里的常量为:public static final int INT_FOUR_KB = 4096;
            keyPairGen.initialize(MagicNum.INT_FOUR_KB, new SecureRandom());
            // 生成一个密钥对,保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();
            //私钥
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            //公钥
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
    
            /**
             * 公钥与私钥
             */
            String publicKey = new String(Base64.encodeBase64(rsaPublicKey.getEncoded()));
            String privateKey = new String(Base64.encodeBase64((rsaPrivateKey.getEncoded())));
            /**
             * 存入Redis
             */
            redisOperation.set(RedisKeyConstant.SYSTEM_RAS_PUBLIC,publicKey);
            redisOperation.set(RedisKeyConstant.SYSTEM_RAS_PRIVATE,privateKey);
        }
    
        /**
         * 解密方法
         *
         * @param password -
         * @return ProcessException 自定义异常类
         */
        public String decrypt(String password) {
            try {
                return RsaUtil.decrypt(password, getPrivateKey());
            } catch (Exception e) {
                e.printStackTrace();
                throw new ProcessException(CommonConstants.ENUM_PROCESSING_EXCEPTION,"RSA解密异常");
            }
        }
    
        /**
         * 加密方法
         *
         * @param password -
         * @return -
         * @exception ProcessException 自定义异常类
         */
        public String encrypt(String password) {
            try {
                return RsaUtil.encrypt(password, getPublicKey());
            } catch (Exception e) {
                throw new ProcessException(CommonConstants.ENUM_PROCESSING_EXCEPTION,"RSA加密异常");
            }
        }
    
        /**
         * 获取公钥
         */
        public String getPublicKey() {
            return redisOperation.get(RedisKeyConstant.SYSTEM_RAS_PUBLIC);
        }
    
        /**
         * 获取私钥
         */
        public String getPrivateKey() {
            return redisOperation.get(RedisKeyConstant.SYSTEM_RAS_PRIVATE);
        }
    }
    
  2. RsaUtil工具类,提供Base编码和解码
    public final class RsaUtil {
    
        private static final String RSA = "RSA";
    
        /**
         * RSA公钥加密
         *
         * @param publicKey publicKey
         * @param str       加密字符串
         * @return 密文
         * @throws Exception 加密过程中的异常信息
         */
        public static String encrypt(String str, String publicKey) throws Exception {
            //base64编码的公钥
            byte[] decoded = Base64.decodeBase64(publicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA);
            PublicKey pubKey = keyFactory.generatePublic(keySpec);
            //RSA加密
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
        }
    
        /**
         * RSA私钥解密
         *
         * @param privateKey privateKey
         * @param str        加密字符串
         * @return 明文
         */
        public static String decrypt(String str, String privateKey) throws Exception {
            //64位解码加密后的字符串
            byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
            //base64编码的私钥
            byte[] decoded = Base64.decodeBase64(privateKey);
            RSAPrivateKey priKey =
                    (RSAPrivateKey) KeyFactory.getInstance(RSA).generatePrivate(new PKCS8EncodedKeySpec(decoded));
            //RSA解密
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            return new String(cipher.doFinal(inputByte));
        }
    }
    
  3. 在Controller层编写接口以便做后面的测试
    @RestController
    @RequestMapping("/part/util")
    public class UtilController {
         @Autowired
         private RsaService rsaService;
        /**
          * 获取公钥
          *
          * @return -
          */
         @ApiOperation("获取公钥")
         @GetMapping("getPublicKey")
         public Result getPublicKey() {
             return Result.ok().data(rsaService.getPublicKey());
         }
    
         /**
          * 获取加密字符串
          *
          * @param key -
          * @return -
          */
         @ApiOperation("获取加密字符串")
         @GetMapping("encrypt/key")
         public Result getText(@RequestParam(value = "key") String key) {
             String encryptKey = rsaService.encrypt(key);
             return Result.ok().data(encryptKey);
         }
    
         /**
          * 获取解密字符串
          *
          * @param encryptKey -
          * @return -
          */
         @ApiOperation("获取解密字符串")
         @GetMapping("decrypt/key")
         public Result getText2(@RequestParam(value = "encryptKey") String encryptKey) {
             String decryptKey = rsaService.decrypt(encryptKey);
             return Result.ok().data(decryptKey);
         }
    }
    
测试结果
  • 获取公钥接口

    在这里插入图片描述

  • 加密接口,输入参数key将与公钥加密,接口返回得到加密后的字符串。

    在这里插入图片描述

  • 解密接口,输入参数为公钥加密后的字符串,接口将返回私钥解密后的结果。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1381980.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL面试题 | 05.精选MySQL面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

小程序中滚动字幕

需求&#xff1a;在录像时需要在屏幕上提示字幕&#xff0c;整体匀速向上滚动 html部分&#xff1a; <view class"subtitles_main"><view style"font-size:34rpx;color: #fff;line-height: 60rpx;" animation"{{animation}}">人生的…

Spring Boot 整合支付宝实现在线支付方案(沙箱环境)

文章目录 1.理解沙箱环境2.沙箱环境接入准备2.1 访问开发者控制台2.2 获取重要信息2.3 处理秘钥 3.接入支付宝支付的流程4.实现支付4.1 添加 SDK 依赖4.2 创建配置类4.3 支付宝订单管理接口实现流程4.4 支付宝支付接口实现流程 5.支付宝支付功能演示7.总结 TIP&#xff1a;对于…

VMware workstation安装debian-12.1.0虚拟机(最小化安装)并配置网络

VMware workstation安装debian-12.1.0虚拟机&#xff08;最小化安装&#xff09;并配置网络 Debian 是一个完全自由的操作系统&#xff01;Debian 有一个由普罗大众组成的社区&#xff01;该文档适用于在VMware workstation平台安装最小化安装debian-12.1.0虚拟机。 1.安装准…

YOLOv5改进 | 注意力篇 | CGAttention实现级联群体注意力机制 (全网首发改进)

一、本文介绍 本文给大家带来的改进机制是实现级联群体注意力机制CascadedGroupAttention,其主要思想为增强输入到注意力头的特征的多样性。与以前的自注意力不同,它为每个头提供不同的输入分割,并跨头级联输出特征。这种方法不仅减少了多头注意力中的计算冗余,而且通过增…

YOLOv5改进 | 二次创新篇 | 结合iRMB和EMA形成全新的iEMA机制(全网独家创新)

一、本文介绍 本文给大家带来的改进机制是二次创新的机制,二次创新是我们发表论文中关键的一环,为什么这么说,从去年的三月份开始对于图像领域的论文发表其实是变难的了,在那之前大家可能搭搭积木的情况下就可以简单的发表一篇论文,但是从去年开始单纯的搭积木其实发表论…

序章 熟悉战场篇—了解vue的基本操作

了解vue 的基本目录&#xff1a; dist 是打包后存放的目录(后续可以改)node_modules 是依赖包public 是静态index页面src 是存放文件的目录assets 是存放静态资源的目录components 是存放组件的目录views 是存放页面文件的目录&#xff08;没有views 自己新建一个&#xff09;A…

【一】通信协议概述

通信协议概述 简介&#xff1a; 很早之前就思考了要写一下电力系统常用的几种通信协议&#xff0c;一直拖着也没有行动&#xff0c;这次终于下定决心来出一个《通信协议》这样的专栏。电力行业数字化方面资料较少&#xff0c;我理解主要一方面是数字化程度还不高&#xff0c;一…

小程序基础学习(js混编)

在组件中使用外部js代码实现数据改变 先创建js文件 编写一些组件代码 编写外部js代码 在组件的js中引入外部js 在 app.json中添加路径规则 组件代码 <!--components/my-behavior/my-behavior.wxml--> <view><view>当前计数为{{count}}</view> <v…

java自动化将用例和截图一起执行测试放入world中直接生成测试报告【搬代码】

1.首先我们得用例写好之后放入文档中&#xff0c;把不用的案例类型、前置条件去掉之后&#xff0c;如图&#xff1a; 放到桌面后&#xff0c;先看执行结果&#xff1a; 直接上代码 package com.znzdh.qitagongju;import jxl.Sheet; import jxl.Workbook; import org.apache…

SpringBoot读取配置文件中的内容

文章目录 1. 读取配置文件application.yml中内容的方法1.1 Environment1.2 Value注解1.3 ConfigurationProperties 注解1.4 PropertySources 注解&#xff0c;获取自定义配置文件中的内容&#xff0c;yml文件需要自行实现适配器1.5 YamlPropertiesFactoryBean 加载 YAML 文件1.…

Java面试基础|数据结构 -实时更新

1.HashMap和ConcurrentHashMap介绍 核心是一个Node数组&#xff0c;数据结构与hashMap相似 使用CAS操作来实现无锁的更新&#xff0c;提高了并发性。当更新节点时&#xff0c;它会使用CAS来替换节点的值或链接&#xff0c;如果CAS失败&#xff0c;表明有其他线程也在进行修改&a…

C语言--单链表的创建及使用详解

C语言--单链表的创建及使用详解 1. 单链表定义1.1 工作原理1.2 优点 2. 单链表的创建2.1 文件创建2.2 节点创建2.3 链表显示 3. 链表操作3.1 尾插3.2 头插3.3 尾删3.4 头删3.5 指定数据寻找3.6 指定位置前插入3.7 指定位置删除 4. 单链表总内容4.1 test.c文件4.2 SList.h文件4.…

强化学习应用(一):基于Q-learning的物流配送路径规划研究(提供Python代码)

一、Q-learning算法简介 Q-learning是一种强化学习算法&#xff0c;用于解决基于马尔可夫决策过程&#xff08;MDP&#xff09;的问题。它通过学习一个值函数来指导智能体在环境中做出决策&#xff0c;以最大化累积奖励。 Q-learning算法的核心思想是使用一个Q值函数来估计每…

ubuntu连接xshell怎么连接

在网上找了好多办法都不行 例如 太久没打开Ubuntu可能输入命令查不到IP地址&#xff0c;解决办法也比较简单&#xff0c;首先第一步 确定自己能不能进入管理员root权限&#xff08;输入命令su&#xff09;&#xff0c;如果没有的话得重新配置&#xff0c;如下图 这是因为当前Ub…

DC-DC变换集成电路芯片B34063——工作电压范围宽,静态电流小

B34063为一单片DC-DC变换集成电路&#xff0c;内含温度补偿的参考电压源(1.25V)、比较器、能有效限制电流及控制工作周期的振荡器,驱动器及大电流输出开关管等&#xff0c;外配少量元件&#xff0c;就能组成升压、降压及电压反转型DC-DC变换器。 主要特点&#xff1a; ● 工作…

文本翻译GUI程序,实现简单的英汉互译

项目地址&#xff1a;mendianyu/txtTranslate: 文本翻译GUI程序&#xff0c;实现简单的英汉互译 (github.com) 文本翻译GUI程序&#xff0c;实现简单的英汉互译 项目结构 三个java文件加一个pom文件 项目运行效果 语言可选择en(英语) zh(汉语) auto(自动识别&#xff0c;仅源语…

推荐算法常见的评估指标

推荐算法评估指标比较复杂&#xff0c;可以分为离线和在线两部分。召回、粗排、精排和重排由于定位区别&#xff0c;其评估指标也会有一定区别&#xff0c;下面详细讲解。 1 召回评价体系 召回结果并不是最终推荐结果&#xff0c;其本质是为后续排序层服务的&#xff0c;故核…

【深度学习目标检测】十五、基于深度学习的口罩检测系统-含GUI和源码(python,yolov8)

YOLOv8是一种物体检测算法&#xff0c;是YOLO系列算法的最新版本。 YOLO&#xff08;You Only Look Once&#xff09;是一种实时物体检测算法&#xff0c;其优势在于快速且准确的检测结果。YOLOv8在之前的版本基础上进行了一系列改进和优化&#xff0c;提高了检测速度和准确性。…

通过IP地址识别风险用户

随着互联网的迅猛发展&#xff0c;网络安全成为企业和个人关注的焦点之一。识别和防范潜在的风险用户是维护网络安全的关键环节之一。IP数据云将探讨通过IP地址识别风险用户的方法和意义。 IP地址的基本概念&#xff1a;IP地址是互联网上设备的独特标识符&#xff0c;它分为IP…