RSA非对称加密解密,前端公钥加密后端私钥解密

34 篇文章 1 订阅

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);
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值