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

文章目录

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

前言
  • 非对称加密是指使用不同的两个密钥进行加密和解密的一种加密算法,调用方用使用服务方提供的公钥进行加密,服务方使用自己的私钥进行解密。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将与公钥加密,接口返回得到加密后的字符串。

    在这里插入图片描述

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Open3D 反算点云缩放系数(21)

Open3D 反算点云缩放系数(21) 一、算法介绍二、算法实现1.方法12.方法2(通用)一、算法介绍 上一章按照指定的系数,对点云进行了等比例缩放,这里输入缩放后的两块点云,反算二者之间的缩放系数。 二、算法实现 已知使用的俩点云是1/2的缩放关系,用于验证计算结果是否…

SpringMVC(六)RESTful

1.RESTful简介 REST:Representational State Transfer,表现层资源状态转移 (1)资源 资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件…

解决Unexpected record signature 0X9maven 资源过滤

解决Unexpected record signature: 0X9|maven 资源过滤 记录问题:我们有个需求是根据excel模版导出一个excel表。我们的项目是SpringBoot,所以理所当然的把这个模版文件放到了,resources文件夹中。但是在导出文件的时候却遇到了invalid code …

黑马本地生活(列表页面,详情页面)

🏡浩泽学编程:个人主页 🔥 推荐专栏:《深入浅出SpringBoot》《java项目分享》 《RabbitMQ》《Spring》《SpringMVC》 🛸学无止境,不骄不躁,知行合一 文章目录 前言一、列表页面功…

iPhone“查找”最多可添加32个物品!

对于那些丢三落四的果粉来说,苹果的“查找”功能是一大福音。不管是丢失了iPhone、iPad、Mac、AirPods还是AirTag,都可以通过“查找”功能在地图上追踪设备的位置,甚至是远程锁定或抹掉设备的数据。 那么,iPhone的查找一次能支持添…

关于 ant-design-vue resetFields 失效

关于 ant-design-vue resetFields 失效 背景: 遇到这样的问题使用ant-design-vue useForm来制作表单的时候,resetFields()失效 场景: 编辑 -赋值 新增-初始值(问题点:新增的时候他就不初始化) 方案&…

机器人技能学习-构建自己的数据集并进行训练

概要 若想训练自己的场景,数据集的重要性不做过多赘述,下面就基于 robomimic 和 robosuite 构建自己的数据集进行讲解,同时,也会附上 train 和 run 的流程,这样,就形成了闭环。 自建数据集 采集数据 采…

RabbitMQ学习笔记

介绍 名词解释 Broker:接受和分发消息的应用,例如RabbitMQ Server Virtual host:出于多租户和安全因素设计的,把AMQP的基本组件划分到一个虚拟的分组中,类似于网络中的namespace概念。当多个不同的用户使用同一个RabbitMQ serv…

【SSM框架】SpringMVC

SpringMVC简介 SpringMVC概述 SpringMvC是一种基于Java实现MVC模型的轻量级web框架 SpringMVC技术与Servlet技术功能等同&#xff0c;用于表现层功能开发 SpringMVC入门 1、导入坐标 <dependency><groupId>javax.servlet</groupId><artifactId>ja…

98. 验证二叉搜索树(LeetCode)

文章目录 前言一、题目分析二、算法原理三、代码实现剪枝总结 前言 在本文章中&#xff0c;我们将要详细介绍一下Leetcode中第98题验证二叉搜索树&#xff0c; 在本内容中我们将会学到递归解决二叉树&#xff0c;全局变量&#xff0c;剪枝等等相关内容。 一、题目分析 分析&a…

【LabVIEW FPGA入门】使用数字IO卡实现计数器输入功能

方法1&#xff1a; 1.首先需要用一个数字IO的输入FPGA端口&#xff0c;并将其拖入程序框图中&#xff0c;同时创建一个循环。 2.如果想要在循环中实现累加功能&#xff0c;就可以使用移位寄存器。 数字输入的当前值和历史值进行比较&#xff0c;用于一个判断大于&#xff0c;来…

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

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

【论文阅读笔记】MobileSal: Extremely Efficient RGB-D Salient Object Detection

1.介绍 MobileSal: Extremely Efficient RGB-D Salient Object Detection MobileSal&#xff1a;极其高效的RGB-D显著对象检测 2021年发表在 IEEE Transactions on Pattern Analysis and Machine Intelligence。 Paper Code 2.摘要 神经网络的高计算成本阻碍了RGB-D显着对象…

SEU编译原理复习(期末考试用)——知识点+习题练习

这里给大家推荐下另一位博主的文章&#xff0c;我第一遍是看着这篇文章课本老师的复习PPT一起过的&#xff0c;二遍是做的作业题和老师发的往年卷&#xff1a;编译原理 乱七八糟的期末复习笔记_东南大学编译原理期末复习-CSDN博客 一、语言和文法&#xff08;10分&#xff09;…

CentOS7本地部署分布式开源监控系统Zabbix并结合内网穿透实现远程访问

前言 Zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 本地zabbix web管理界面限制在只能局域…

专业120+总分420+中山大学884信号与系统考研经验信息与通信工程电子信息

今年考研专业课120&#xff0c;总分420&#xff0c;顺利上岸。本人本科211末流&#xff0c;本科期间比较散漫&#xff0c;没有拿到本校保研资格&#xff0c;作为北方孩子&#xff0c;一直想到东南沿海地区&#xff0c;考研再三选择中山大学信通&#xff0c;该收心时候还是得逼一…

解决Spss没有创建虚拟变量的选项的问题

这个是今天用spss想创建虚拟变量然后发现我的spss没有。 然后能怎么办我就百度呗&#xff0c; 说是在扩展里连接扩展中心 天哪&#xff0c;谁能连上&#xff0c;我连不上 于是就找到了从github上下载到本地&#xff0c;然后安装到spss中 目录 解决方法 点击code 再点击D…

buuctf-Misc 题目解答分解115-117

115.派大星的烦恼 解压下载文件时一个 bmp 文件&#xff0c;用notepad 打开有没有发现什么 &#xff0c;提示位图什么的 用Stegsolve.jar 打开 发现很多. 和- 第一时间想到了 电报码 但提示不是电报码&#xff0c;除了这个那就是很像二进制了 0,1 什么的&#xff0c;但这个感觉…

HTML--表单

睡不着就看书之------------------------ 表单 作用&#xff1a;嗯~~动态页面需要借助表单实现 表单标签&#xff1a; 主要分五种&#xff1a; form&#xff0c;input&#xff0c;textarea&#xff0c;select&#xff0c;option 从外观来看&#xff0c;表单就包含以下几种&…

SpringBoot知识03

1、多模块项目无法启动&#xff0c;报错Failed to execute goal on project*: Could not resolve dependencies for project