RSA加密的使用(前后端)

公钥(publicKey)加密、私钥(privateKey)解密。不能逆向,私钥(privateKey)加密、公钥(publicKey)解密。说白了就是前后端都需要用公钥(publicKey)进行加密,用私钥(privateKey)进行解密。

引入前端 JS 库:jsencrypt.js

npm install jsencrypt 

使用

后端生成RSAUtil工具类

public class RSAUtil {static {Security.addProvider(new BouncyCastleProvider());}/*** 随机生成密钥对** @param filePath 密钥对要存储的路径*/public static void genKeyPair(String filePath) {// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象KeyPairGenerator keyPairGen = null;try {keyPairGen = KeyPairGenerator.getInstance("RSA");} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 初始化密钥对生成器,密钥大小为96-1024位keyPairGen.initialize(1024, new SecureRandom());// 生成一个密钥对,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();// 得到私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();// 得到公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();try {// 得到公钥字符串String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());// 得到私钥字符串String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());// 将密钥对写入到文件FileWriter pubfw = new FileWriter(filePath + "/publicKey.key");FileWriter prifw = new FileWriter(filePath + "/privateKey.key");BufferedWriter pubbw = new BufferedWriter(pubfw);BufferedWriter pribw = new BufferedWriter(prifw);pubbw.write(publicKeyString);pribw.write(privateKeyString);pubbw.flush();pubbw.close();pubfw.close();pribw.flush();pribw.close();prifw.close();} catch (Exception e) {e.printStackTrace();}}
}/*** 去除密钥的多余信息** @param key 公钥或私钥字符串* @return Base64的密钥 base 64 key*/public static String getBase64Key(String key) {key = key.replaceAll("-----BEGIN (.*)-----", "");key = key.replaceAll("-----END (.*)----", "");key = key.replaceAll("\r\n", "");key = key.replaceAll("\n", "");return key;}/*** 从文件中加载密钥** @param fileName 公钥或私钥的文件名* @return 字符串形式的密钥 ,去除-----BEGIN (.*)-----等多余信息*/public static String loadKeyFromFile(String fileName) {byte[] keyBytes = loadRawKeyFromFile(fileName);// convert to der formatreturn getBase64Key(new String(keyBytes));}/*** 从文件中加载密钥** @param fileName 公钥或私钥的文件名* @return 字符串形式的密钥 byte [ ]*/public static byte[] loadRawKeyFromFile(String fileName) {InputStream resourceAsStream = RSAUtil.class.getClassLoader().getResourceAsStream(fileName);DataInputStream dis = new DataInputStream(resourceAsStream);byte[] keyBytes = null;try {keyBytes = new byte[resourceAsStream.available()];dis.readFully(keyBytes);dis.close();} catch (IOException e) {throw new SystemException("Failed to load public key from file '" + fileName + "'", e);}return keyBytes;}/*** Load private key by str rsa private key.* 加载秘钥* @param privateKeyStr the private key str* @return the rsa private key*/public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr) {try {byte[] buffer = Base64.getDecoder().decode(privateKeyStr);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC"); // KeyFactory.getInstance("RSA");return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);} catch (NoSuchAlgorithmException e) {throw new SystemException("无此算法", e);} catch (InvalidKeySpecException e) {throw new SystemException("私钥非法", e);} catch (NullPointerException e) {throw new SystemException("私钥数据为空", e);} catch (NoSuchProviderException e) {throw new SystemException("no such provider: RSA, BC", e);}}/*** 公钥加密过程** @param publicKey     公钥* @param plainTextData 明文数据* @return 密文 byte [ ]*/public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) {if (publicKey == null) {throw new SystemException("加密公钥为空");}Cipher cipher = null;try {// 使用默认RSAcipher = Cipher.getInstance("RSA");// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] output = cipher.doFinal(plainTextData);return output;} catch (NoSuchAlgorithmException e) {throw new SystemException("无此加密算法", e);} catch (NoSuchPaddingException e) {throw new SystemException("无此加密算法", e);} catch (InvalidKeyException e) {throw new SystemException("加密公钥非法,请检查", e);} catch (IllegalBlockSizeException e) {throw new SystemException("明文长度非法", e);} catch (BadPaddingException e) {throw new SystemException("明文数据已损坏", e);}}/*** 私钥加密过程** @param privateKey    私钥* @param plainTextData 明文数据* @return 密文 byte [ ]* @throws Exception 加密过程中的异常信息*/public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData) throws Exception {if (privateKey == null) {throw new SystemException("加密私钥为空");}Cipher cipher = null;try {// 使用默认RSAcipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");// Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, privateKey);byte[] output = cipher.doFinal(plainTextData);return output;} catch (NoSuchAlgorithmException e) {throw new SystemException("无此加密算法", e);} catch (NoSuchPaddingException e) {throw new SystemException("系统中无此填充机制", e);} catch (InvalidKeyException e) {throw new SystemException("加密私钥非法,请检查", e);} catch (IllegalBlockSizeException e) {throw new SystemException("明文长度非法", e);} catch (BadPaddingException e) {throw new SystemException("明文数据已损坏", e);}}/*** 私钥解密过程** @param privateKey 私钥* @param cipherData 密文数据* @return 明文 byte [ ]*/public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) {if (privateKey == null) {throw new SystemException("解密私钥为空");}Cipher cipher = null;try {// 使用默认RSAcipher = Cipher.getInstance("RSA");// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] output = cipher.doFinal(cipherData);return output;} catch (NoSuchAlgorithmException e) {throw new SystemException("无此解密算法", e);} catch (NoSuchPaddingException e) {throw new SystemException("系统中无此填充机制", e);} catch (InvalidKeyException e) {throw new SystemException("解密私钥非法", e);} catch (IllegalBlockSizeException e) {throw new SystemException("密文长度非法");} catch (BadPaddingException e) {throw new SystemException("密文数据已损坏", e);}}/*** 公钥解密过程** @param publicKey  公钥* @param cipherData 密文数据* @return 明文 byte [ ]* @throws Exception 解密过程中的异常信息*/public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData) throws Exception {if (publicKey == null) {throw new SystemException("解密公钥为空");}Cipher cipher = null;try {// 使用默认RSAcipher = Cipher.getInstance("RSA");// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());cipher.init(Cipher.DECRYPT_MODE, publicKey);byte[] output = cipher.doFinal(cipherData);return output;} catch (NoSuchAlgorithmException e) {throw new SystemException("无此解密算法", e);} catch (NoSuchPaddingException e) {throw new SystemException("系统中无此填充机制", e);} catch (InvalidKeyException e) {throw new SystemException("解密公钥非法", e);} catch (IllegalBlockSizeException e) {throw new SystemException("密文长度非法");} catch (BadPaddingException e) {throw new SystemException("密文数据已损坏");}}

前端加密

const JSEncrypt = window.JSEncrypt;export function rsa(str) {const jse = new JSEncrypt();const { publicKey } = xxx;//从后端接口获取publicKeyjse.setPublicKey(publicKey);return jse.encrypt(str)
}export default function(str) {return rsa(str)
}export const decrypt = async str => {return new Promise((resolve, reject) => {后端解密接口(str).then(res => {if (res.data.code === "success") {resolve(res.data.data);} else {reject(res);}}).catch(err => {reject(err)});})
}

后端解密接口

//eg: 后端获取publicKey接口
@GetMapping("getRsaPublicKey")
public ResultResp<String> getRsaPublicKey() {String key = RSAUtil.loadKeyFromFile("rsaPublicKey.key");return success(key);
}//eg:后端解密接口
@GetMapping("getDecryptRsaPwd")
public Result<Object> getDecryptRsaPwd(String rsaPwd) {//对传进来的字符串做处理,把空格更改成“+”号String s = rsaPwd.replaceAll(" +", "+");String privateKeyStr = RSAUtil.loadKeyFromFile("rsaPrivateKey.key");// rsa解密byte[] cipherData = Base64.getDecoder().decode(rsaPwd);byte[] xpwd = RSAUtil.decrypt(RSAUtil.loadPrivateKeyByStr(privateKey), cipherData);String  decryptRsaPwd = new String(xpwd);return Result.success(decryptRsaPwd);
}

使用

import encrypt, { decrypt } from '@/utils/xxx;//引入上面写的前端前端文件
//加密密码
data.password = encrypt(data.password); 
//解密
decrypt(this.password).then(clearText => {this.model.password = clearText
})

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

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

相关文章

【JavaEESpring】认识Spring

认识Spring 1. 什么是框架2. SpringBoot 介绍2.1 Spring 的介绍2.2 SpringBoot 1. 什么是框架 框架(Framework) &#xff0c;意思是框架、机制、准则。通俗的来讲: 框架是实现某种功能的半成品, 他提供了⼀些常⽤的⼯具类, 我们在框架的基础上, 可以更加⾼效的进⾏开发 后端框…

Redis6的IO多线程分析

性能测试 机器配置 C Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 14 On-line CPU(s) list: 0-13 Mem: 62G性能 配置推荐 官方表示&#xff0c;当使用redis时有性能瓶…

vue3接口、数据懒加载,回滚不重复加载

目标&#xff1a;实现当组件进入可视区域在加载数据或者发送请求。 背景&#xff1a;父组件为vxe-table构成的组件、子组件为table的某一列&#xff0c;这一列的数据通过接口返回&#xff0c;有多少条表格数据就会请求多少次接口&#xff0c;为了提升性能&#xff0c;所以采用…

《开箱元宇宙》:认识香港麦当劳通过 The Sandbox McNuggets Land 的 Web3 成功经验

McNuggets Land 是 The Sandbox 于 2023 年发布的最受欢迎的体验之一。在本期的《开箱元宇宙》系列中&#xff0c;我们采访了香港麦当劳数位顾客体验暨合作伙伴资深总监 Kai Tsang&#xff0c;来了解这一成功案例背后的策略。 在不断发展的市场营销和品牌推广领域&#xff0c;不…

Visual Studio 2022 + OpenCV 4.5.2 安装与配置教程

目录 OpenCV的下载与配置Visual Studio 2022的配置新建工程新建文件新建项目属性表环境配置测试先写一个输出将OpenCV的动态链接库添加到项目的 x64 | Debug下测试配置效果 Other OpenCV的下载与配置 参考这个OpenCV的下载与环境变量的配置&#xff1a; Windows10CLionOpenCV4…

网络原理---拿捏HTTP协议:请求和响应

文章目录 认识请求首行URLURL的格式URL的encode和decode 版本号方法GET方法POST方法GET VS POST 请求头&#xff1a;headerHostContent-Length 和 Content-TypeUser-Agent&#xff08;UA&#xff09;RefererCookie 空行正文&#xff1a;body如何构造HTTP请求&#xff1f;浏览器…

ARMday04(开发版简介、LED点灯)

开发版简介 开发板为stm32MP157AAA,附加一个拓展版 硬件相关基础知识 PCB PCB&#xff08; Printed Circuit Board&#xff09;&#xff0c;中文名称为印制电路板&#xff0c;又称印刷线路板&#xff0c;是重要的电子部件&#xff0c;是电子元器件的支撑体&#xff0c;是电子…

Linux生成随机密码和根据密码批量生成用户

cat /dev/urandom|tr -dc [:alnum:]|head -c20 生成20位数字字母的随机密码。 /dev/urandom生成随机数&#xff0c;tr -dc [:alnum:] 保留所有数字和字母&#xff0c;head -c20保留前20位。 使用原生的Linux命令生成可以说是极度安全的&#xff0c;也适用于批量用户生成的情况…

Django中如何让DRF的接口针对前后台返回不同的字段

在Django中&#xff0c;使用Django Rest Framework&#xff08;DRF&#xff09;时&#xff0c;可以通过序列化器&#xff08;Serializer&#xff09;和视图&#xff08;View&#xff09;的组合来实现前后台返回不同的字段。这通常是因为前后台对数据的需求不同&#xff0c;或者…

AlphaControls控件TsRadioGroup的使用

通常使用AlphaControls控件中的TsRadioGroup时&#xff0c;往往使用默认值&#xff0c;会造成TsRadioGroup标题被TsRadioGroup的ITEMs占用&#xff0c;严重影响美观&#xff1a; 解决方案&#xff0c;通过对TsRadioGroup的ContentVOffset属性&#xff0c;设置为10。即可立即改善…

处理uniapp打包后有广告的问题

1、登录平台&#xff08;开发者中心&#xff09; 2、 3、 4、 5、

3线硬件SPI+DMA驱动 HX8347 TFT屏-快速显示文字

本文实现DMA快速显示文字 汉字点阵通常是16*16点阵&#xff0c;那么用DMA一次性显示汉字&#xff0c;应该至少申请480*16个字节的空间&#xff0c;用于显示一行文字&#xff0c;其中480是屏幕一行用DMA驱动所需内存。 一、 源码 HX8347.h #ifndef USER_HX8347_H_ #define USE…

回归预测 | Matlab实现PCA-PLS主成分降维结合偏最小二乘回归预测

回归预测 | Matlab实现PCA-PLS主成分降维结合偏最小二乘回归预测 目录 回归预测 | Matlab实现PCA-PLS主成分降维结合偏最小二乘回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现PCA-PLS主成分降维结合偏小二乘回归预测&#xff08;完整源码和数据) 1.输…

2023年9月少儿编程 中国电子学会图形化编程等级考试Scratch编程二级真题解析(选择题)

2023年9月scratch编程等级考试二级真题 选择题(共25题,每题2分,共50分) 1、点击绿旗,运行程序后,舞台上的图形是 A、画笔粗细为4的三角形 B、画笔粗细为5的六边形 C、画笔粗细为4的六角形 D、画笔粗细为5的三角形 答案:D 考点分析:考查积木综合使用,重点考查画笔…

伪造referer [极客大挑战 2019]Http1

打开题目 没有发现什么&#xff0c;我们查看源代码 在这里我们发现了提示 访问一下页面得到 提示说不能来自于https://Sycsecret.buuoj.cn&#xff0c;我们尝试访问一下这个url 发现访问不了 我们bp抓包一下 伪造个referer头 referer:https://Sycsecret.buuoj.cn 发包过去…

【js逆向实战】某sakura动漫视频逆向

写在前面 再写一个逆向实战&#xff0c;后面写点爬虫程序来实现一下。 网站简介与逆向目标 经典的一个视频网站&#xff0c;大多数视频网站走的是M3U8协议&#xff0c;就是一个分段传输&#xff0c;其实这里就有两个分支。 通过传统的m3u8协议&#xff0c;我们可以直接进行分…

如何申请QQ邮箱的SMTP密钥简洁版

QQ 邮箱的 SMTP 密钥通常称为"SMTP 授权码"&#xff0c;你可以按照以下步骤找到它&#xff1a; 1.登录 QQ 邮箱&#xff1a;打开 QQ 邮箱登录页面&#xff0c;并使用你的 QQ 账号和密码登录。 2.进入设置页面&#xff1a;在 QQ 邮箱页面中&#xff0c;点击顶部的&q…

MySQL篇之mysql主从集群搭建

一、MySQL集群架构的介绍 我们在使用MySQL数据库的时候&#xff0c;只是一个单机的数据库服务。在实际的生产环境中&#xff0c;数据量可能会非常庞大&#xff0c;这样单机服务的MySQL在使用的时候&#xff0c;性能会受到影响。并且单机的数据安全想也会受到影响。因此在生产黄…

制作一个模板三

您已经看到了Jinja2在呈现过程中如何用实际值替换占位符&#xff0c;但这只是Jinja2在模板文件中支持的众多强大操作之一。例如&#xff0c;模板还支持在{%…%}块。下一个版本的index.html模板增加了一个条件语句: app/templates/index.html: <!doctype html> <htm…

快速开发一个简单实用的MES系统?

题主在一个光伏组件工厂做生产管理&#xff0c;但工厂竟然没有MES系统&#xff0c;于是想自己开发一个简单的MES系统。那么我们来看看题主对于开发MES系统的要求—— 对系统&#xff1a;每一个产品都有一个条形码&#xff0c;希望系统可以追踪生产计划下的产品的生产状态&…