RSA非对称加密解密,前端公钥加密后端私钥解密,可以防止陌生人直接通过后端接口篡改数据。有数据泄露的风险。
前端:Vue框架
后端:sprintboot(Java)
工具类:hutool
前端Vue获取公钥:
这里安装jsencrypt这个库进行RSA的加密
npm i jsencrypt --force
通过后端接口getJSEncryptPublic获取公钥之后,直接套函数加密
/**
* 前端vue公钥加密,后段私钥解密
* @return
*/
@GetMapping("/getJSEncryptPublic")
public String getJSEncryptPublic(){
String str = (String)stringRedisTemplate.opsForValue().get("privateKey");
if (StringUtils.isNotBlank(str)){
stringRedisTemplate.delete("privateKey");
}
Map<String, String> mapKeyPair = getMapKeyPair();
this.privateKey = mapKeyPair.get("privateKey");
stringRedisTemplate.opsForValue().set("privateKey",this.privateKey,15, TimeUnit.MINUTES);
this.publicKey = mapKeyPair.get("publicKey");
return this.publicKey;
}
/**
* 获取私钥,公钥
* @return
*/
public static Map<String,String> getMapKeyPair() {
// String privateKey = bytesToBase64(getRsaKey().getPrivate().getEncoded());
// String publicKey = bytesToBase64(getRsaKey().getPublic().getEncoded());
// 生成对象,包含钥匙一对
RSA rsa = new RSA();
// 提取公钥并转成base64编码
String publicKeyBase64 = rsa.getPublicKeyBase64();
// 提取私钥并转成base64编码
String privateKeyBase64 = rsa.getPrivateKeyBase64();
Map<String,String> map = new HashMap<>();
//privateKey 私钥
map.put("privateKey",privateKeyBase64);
//publicKey 公钥
map.put("publicKey",publicKeyBase64);
return map;
}
import JSEncrypt from 'jsencrypt/bin/jsencrypt';
axios.get('http://localhost:8887/jing/Xqy/user/getJSEncryptPublic'
).then(reponse =>{
console.log("加密加密:",reponse.data);
const publicKey = reponse.data // 提取公钥
// 获取密码对象
const encryptor = new JSEncrypt()
// 放入公钥
encryptor.setPublicKey(publicKey)
// 放入加密的内容,并加密
this.passByPublicKey = encryptor.encrypt(this.ruleFormLogin.pass)
// 加密后的密文
console.log("passByPublicKey:"+this.passByPublicKey)
//调用queryzhuce()传密文
之后在以密文的形式传给后端(这里调用登录接口queryzhuce()方法),然后后端利用私钥解密获取到真正的明文。
后端获取密文并解密:
如下此时pass是加密后的密文
@GetMapping("/queryZhuce")
public List<CaiwuUser> queryZhuce(@RequestParam(name = "username",required = false)String username,
@RequestParam(name = "pass",required = false)String pass,
HttpServletRequest request){
//解密
String decyptByRSAPass = getDecyptByRSA(pass, this.privateKey, this.publicKey);
System.out.println("decyptByRSAPass:"+decyptByRSAPass);
return xqyService.queryZhuce(username,decyptByRSAPass,request);
}
/**
* 私钥解密
* @param rsaPass
* @param privateKey
* @return
*/
public static String getDecyptByRSA(String rsaPass,String privateKey,String publicKeyStr){
RSA rsa = new RSA(privateKey, null);
String s = rsa.decryptStr(rsaPass, KeyType.PrivateKey, CharsetUtil.CHARSET_UTF_8);
//String s = new String(decrypt, CharsetUtil.CHARSET_UTF_8);
return s;
}
RSA非对称加密公共类
RSAUtil类:
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import com.alibaba.fastjson.JSON;
import com.richfit.richfit.dto.AllDataDto;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* RSA加密解密验签
*/
public class RSAUtil {
/**
* 获取私钥,公钥
* @return
*/
public static Map<String,String> getMapKeyPair() {
// String privateKey = bytesToBase64(getRsaKey().getPrivate().getEncoded());
// String publicKey = bytesToBase64(getRsaKey().getPublic().getEncoded());
// 生成对象,包含钥匙一对
RSA rsa = new RSA();
// 提取公钥并转成base64编码
String publicKeyBase64 = rsa.getPublicKeyBase64();
// 提取私钥并转成base64编码
String privateKeyBase64 = rsa.getPrivateKeyBase64();
Map<String,String> map = new HashMap<>();
map.put("privateKey",privateKeyBase64);
map.put("publicKey",publicKeyBase64);
return map;
}
public static void main(String[] args) {
Map<String, String> mapKeyPair = getMapKeyPair();
AllDataDto allDataDto = new AllDataDto(null,mapKeyPair.get("privateKey"),mapKeyPair.get("publicKey"),null);
System.out.println(JSON.toJSONString(allDataDto));
}
/**
* 私钥解密
* @param rsaPass
* @param privateKey
* @return
*/
public static String getDecyptByRSA(String rsaPass,String privateKey,String publicKeyStr){
RSA rsa = new RSA(privateKey, null);
String s = rsa.decryptStr(rsaPass, KeyType.PrivateKey, CharsetUtil.CHARSET_UTF_8);
//String s = new String(decrypt, CharsetUtil.CHARSET_UTF_8);
return s;
}
/**
* 生成私钥和公钥
* @return
*/
public static KeyPair getRsaKey(){
//生成RSA私钥
KeyPair pair = SecureUtil.generateKeyPair("RSA");
return pair;
}
/**
* 生成私钥
* @return
*/
public static String getRsaPrivateKey(){
//生成RSA私钥
KeyPair pair = SecureUtil.generateKeyPair("RSA");
PrivateKey privateKey = pair.getPrivate();
return bytesToBase64(privateKey.getEncoded());
}
/**
* 生成公钥
* @return
*/
public static String getRsaPublicKey(){
//生成RSA私钥
KeyPair pair = SecureUtil.generateKeyPair("RSA");
PrivateKey privateKey = pair.getPrivate();
return bytesToBase64(privateKey.getEncoded());
}
/**
* 根据入参生成公钥,私钥,验签
* @param text
* @return
*/
public static AllDataDto getAllRsaObject(String text){
if (StrUtil.isBlank(text)){
throw new RuntimeException("参数不能为空!");
}
text = text.trim();
Map<String,String> map = getMapKeyPair();
Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, map.get("privateKey"), map.get("publicKey"));
//签名
byte[] data = text.getBytes(StandardCharsets.UTF_8);
byte[] signed = sign.sign(data);
String signedStr = bytesToBase64(signed);
System.out.println("签名:" + signedStr);
//验证签名
boolean verify = sign.verify(data, base64ToBytes(signedStr));
System.out.println("验签:" + verify);
AllDataDto allDataDto = new AllDataDto(signedStr, map.get("privateKey"), map.get("publicKey"), text);
System.out.println("allDataDto:" + JSON.toJSON(allDataDto));
return allDataDto;
}
// public static void main(String[] args) {
// Map<String, String> map = getMapKeyPair();
// String sign = getSign("123",map.get("privateKey"),map.get("publicKey"));
// System.out.println("签名:"+sign);
// }
// public static void main(String[] args) {
// String text = "人最宝贵的是生命.生命对每个人只有一次.人的一生应当这样度过:当他回首往事的时候,不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻.这样,在临死的时候,他能够说:“我已把自己的整个的生命和全部的精力献给了世界上最壮丽的事业---------为人类的解放而斗争.”";
// System.out.println("原文:" + text);
//
// //生成公私钥对
// KeyPair pair = SecureUtil.generateKeyPair("RSA");
// PrivateKey privateKey = pair.getPrivate();
// PublicKey publicKey = pair.getPublic();
// //获得私钥
// String privateKeyStr = bytesToBase64(privateKey.getEncoded());
// System.out.println("私钥:" + privateKeyStr);
// //获得公钥
// String publicKeyStr = bytesToBase64(publicKey.getEncoded());
// System.out.println("公钥:" + publicKeyStr);
//
// RSA rsa = new RSA(privateKeyStr, publicKeyStr);
// System.out.println(rsa);
//
// //公钥加密,私钥解密
// byte[] encrypt = rsa.encrypt(StrUtil.bytes(text, CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
// System.out.println("公钥加密:" + bytesToBase64(encrypt));
//
// byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);
// System.out.println("私钥解密:" + new String(decrypt,StandardCharsets.UTF_8));
//
//私钥加密,公钥解密
byte[] encrypt2 = rsa.encrypt(StrUtil.bytes(text, CharsetUtil.CHARSET_UTF_8), KeyType.PrivateKey);
System.out.println("私钥加密:" + bytesToBase64(encrypt2));
byte[] decrypt2 = rsa.decrypt(encrypt2, KeyType.PublicKey);
System.out.println("公钥解密:" + bytesToBase64(decrypt2));
//
// Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKeyStr, publicKeyStr);
// //签名
// byte[] data = text.getBytes(StandardCharsets.UTF_8);
// byte[] signed = sign.sign(data);
// String signedStr = bytesToBase64(signed);
// System.out.println("签名:" + signedStr);
//
// //验证签名
// boolean verify = sign.verify(data, base64ToBytes(signedStr));
// System.out.println("验签:" + verify);
//
// }
/**
* 验证签名
* @param text 入参
* @param signedStr 签名
* @param privateKeyStr 私钥
* @param publicKeyStr 公钥
* @return 签名是否合法
*/
public static Boolean verifySign(String text,String signedStr,String privateKeyStr,String publicKeyStr){
Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKeyStr, publicKeyStr);
//验证签名
boolean verify = sign.verify(text.getBytes(StandardCharsets.UTF_8), base64ToBytes(signedStr));
System.out.println("验签:" + verify);
return verify;
}
/**
* 字节数组转Base64编码
*
* @param bytes 字节数组
* @return Base64编码
*/
private static String bytesToBase64(byte[] bytes) {
byte[] encodedBytes = Base64.getEncoder().encode(bytes);
return new String(encodedBytes, StandardCharsets.UTF_8);
}
/**
* Base64编码转字节数组
*
* @param base64Str Base64编码
* @return 字节数组
*/
private static byte[] base64ToBytes(String base64Str) {
byte[] bytes = base64Str.getBytes(StandardCharsets.UTF_8);
return Base64.getDecoder().decode(bytes);
}
}