2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > vue前端RSA加密java后端解密的方法

vue前端RSA加密java后端解密的方法

时间:2020-01-29 05:00:35

相关推荐

vue前端RSA加密java后端解密的方法

一、前言

最近安全测试的总是测出安全漏洞来,让开发改。

想了想干脆把请求参数都加密下,前端加密后端解密,这样总差不多了。

看了下AES加密,是对称的,前后端用这个不太行。

于是想到用RSA加密,是非对称的,可以前端加密后端解密。

二、前端代码与用法

1.前端是vue项目,使用时,需要先执行:

npm i jsencrypt

把这个依赖下载到node_modules里面。

2.可以增加一个工具类文件:项目名/src/utils/commonUtil.js,内容如下:

import JSEncrypt from "jsencrypt";export default {encodeRSA(word, keyStr) {//这个是公钥,有入参时用入参,没有入参用默认公钥keyStr = keyStr ? keyStr : 'MIGxxxxxxxxxxxxxxxxxxxxxxxxxx';//创建对象const jsRsa = new JSEncrypt();//设置公钥jsRsa.setPublicKey(keyStr);//返回加密后结果return jsRsa.encrypt(word);}}

3.然后,需要使用的地方,就可以这样用:

//引入第2步的工具类import commonUtil from '@utils/commonUtil'//引入一个发请求的方法,这个也需要npm iimport axios from 'axios'//一个发请求用的方法export function myget(userId) {return axios.get(`/xxx/user`, {headers: {//先把参数rsa加密下,再用urlEncoder转下码,然后放header里传给后台userId: encodeURIComponent(commonUtil.encodeRSA(userId, null)),},}).then(res => {return res.data})}

这样,就把加密参数放入header里的userId里了,后台可以取出后解密。

三、后端代码与用法

1.可以先写个工具类,如下:(RSA公钥和私钥可以用这个工具类生成,然后自己记录后使用)

import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import javax.crypto.Cipher;import java.security.KeyFactory;import java.security.Security;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.Map;import java.util.HashMap;import java.security.KeyPairGenerator;import java.security.SecureRandom;import java.security.KeyPair;public class RSAUtil {//公钥,可以写前端public static String public_key="MIGxxxxxx";//私钥,只能放后端public static String private_key="MIICxxxxxxxx";public static void main(String[] args) {//解密数据try {//生成公钥和私钥genKeyPair();String publicKey = keyMap.get(0);//打印出来自己记录下System.out.println("公钥:" + publicKey);String privateKey = keyMap.get(1);//打印出来自己记录下System.out.println("私钥:" + privateKey);//获取到后,可以放这里,测试下能不能正确加解密publicKey = public_key;privateKey = private_key;String orgData = "test";System.out.println("原数据:" + orgData);//加密String encryptStr =encrypt(orgData,publicKey);System.out.println("加密结果:" + encryptStr);//解密String decryptStr = decrypt(encryptStr,privateKey);System.out.println("解密结果:" + decryptStr);} catch (Exception e) {e.printStackTrace();}}/*** RSA公钥加密** @param str 加密字符串* @param publicKey 公钥* @return 密文* @throws Exception 加密过程中的异常信息*/public static String encrypt(String str,String publicKey) throws Exception {//base64编码的公钥byte[] decoded = decryptBASE64(publicKey);Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));//RSA加密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, pubKey);String outStr = encryptBASE64(cipher.doFinal(str.getBytes("UTF-8")));return outStr;}/*** RSA私钥解密** @param str 加密字符串* @param privateKey 私钥* @return 明文* @throws Exception 解密过程中的异常信息*/public static String decrypt(String str, String privateKey) throws Exception {//64位解码加密后的字符串byte[] inputByte = decryptBASE64(str);//base64编码的私钥byte[] decoded = decryptBASE64(privateKey);Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));//RSA解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, priKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;}//编码返回字符串public static String encryptBASE64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}//解码返回bytepublic static byte[] decryptBASE64(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}/*** 密钥长度 于原文长度对应 以及越长速度越慢*/private final static int KEY_SIZE = 1024;/*** 用于封装随机产生的公钥与私钥*/private static Map<Integer, String> keyMap = new HashMap<Integer, String>();/*** 随机生成密钥对* @throws Exception*/public static void genKeyPair() throws Exception {// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");// 初始化密钥对生成器keyPairGen.initialize(KEY_SIZE, new SecureRandom());// 生成一个密钥对,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();// 得到私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();// 得到公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();String publicKeyString = encryptBASE64(publicKey.getEncoded());// 得到私钥字符串String privateKeyString = encryptBASE64(privateKey.getEncoded());// 将公钥和私钥保存到Map//0表示公钥keyMap.put(0, publicKeyString);//1表示私钥keyMap.put(1, privateKeyString);}}

2.使用时,把公钥内容放入前端js,私钥内容就放后端代码里,就可以和前端联调测试了。样例如下:

//测试接口@GetMapping("/xxx/user")public String myget(HttpServletRequest request) {//先用非对称算法RSA解密一下try {//从header里获取到参数String userId = request.getHeader("userId");log.debug("收到userId,内容为:"+userId);//这里解密,注意先用URLDecode处理了下,如果前端没有用的话,这里也不用处理userId = RSAUtil.decrypt(URLDecoder.decode(userId,"UTF-8"), RSAUtil.private_key);log.debug("RSA解密成功,userId为"+userId);} catch (Exception e) {log.error("RSA解密失败",e);//如果解密失败,就返回nullreturn null;}return "成功";}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。