当前位置: 首页 > news >正文

数字信封加解密(RSA+AES)

1.前端加密,后台解密

1)前端加密(vue)

  1. 注意:需要在package.json中添加如下依赖
  "dependencies": {
    "crypto-js": "^4.0.0",
    "jsencrypt": "^3.0.0-rc.1"
   }
  1. 注意:在main.js中引入使用,例如我的加解密js工具类叫做cryptUtils.js
import  CryptoJS from './utils/cryptUtils'
Vue.prototype.cryptoJS = CryptoJS
import { JSEncrypt } from 'jsencrypt'
Vue.prototype.JSEncrypt  =  JSEncrypt
/*
 * @Author: huyangyang 
 * @Date: 2020-06-12 10:58:01 
 * @Last Modified by: huyangyang
 * @Last Modified time: 2020-07-21 14:51:08
 */

import CryptoJS from 'crypto-js'

export default {
    // 加密密请求数据
    encryptData(queryParam){
        //RSA加密
        var AES_KEY=this.generator();
        var AES_IV=this.generator();
        var PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCKrO17v4IfHkDB1glq0v4Xd61gkdlritFtv8KjRZr7tH1OexNKS6buS3AA8vHSj3IGvcl6bQsn5HRPOHhS9uiFsG6eYJPNIbtX6/+zkw/v8F3srsVTNeGYpWMHyGyN+HQ3WTZgRf6cu+AQEcOspltVlK4My7Luf0dE79u5xCN2JwIDAQAB";
        var jsEncrypt = new JSEncrypt();
        jsEncrypt.setPublicKey(PUBLIC_KEY);
        var aesKey = jsEncrypt.encrypt(AES_KEY);
        var aesIv = jsEncrypt.encrypt(AES_IV);
        //AES加密
        var json = JSON.stringify(queryParam);
        json =this.encrypt(json, AES_KEY, AES_IV);
        //组装返回数据
        var returnMap = new Map();
        returnMap.put("aesKey",aesKey);
        returnMap.put("aesIv",aesIv);
        returnMap.put("json",json);
        return returnMap;
    },
    // AES加密
    encrypt(word, keyStr, ivkey) {
        var key = CryptoJS.enc.Utf8.parse(keyStr)
        var iv = CryptoJS.enc.Utf8.parse(ivkey);
        var srcs = CryptoJS.enc.Utf8.parse(word)
        var encrypted = CryptoJS.AES.encrypt(srcs, key, {
            iv: iv,
            mode: CryptoJS.mode.CBC, 
            padding: CryptoJS.pad.Pkcs7
        });
        return encrypted.toString()
    },
    //获取0-15并通过toString转16进制
    generator(){
        var num = '';
        for(var i=0; i<16; i++){
            num += Math.floor(Math.random()*16).toString(16);   
        }
        return num;
    }
}

2)后台解密(java)

			//根据私钥RSA解密出的aesKey和aesIv去AES解密数据json
			String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIqs7Xu/gh8eQMHWCWrS/hd3rWCR2WuK0W2/wqNFmvu0fU57E0pLpu5LcADy8dKPcga9yXptCyfkdE84eFL26IWwbp5gk80hu1fr/7OTD+/wXeyuxVM14ZilYwfIbI34dDdZNmBF/py74BARw6ymW1WUrgzLsu5/R0Tv27nEI3YnAgMBAAECgYA46en5nMp5nP/0zbRFvFx+Iybr+E/kPC/hvA7U1Y9a+GNpH0f2eQAE0r8gFJU81pR0wdV7wl8Ou0sk7EctvZoGCw2R8PU0iMOTYjidzXE38MeXicKeDL2NlJ6NCDE+QfGDaA6kHnJTIppyKKolkoYE5joXRtlHGXxp58/JG9sJUQJBAPuTFiviz/N4ACY1d6gz8gvaLE/M5PE/eLbKjEIdgzoAu0ToMsKYvth1/pf7Fy4bxCKYLcgVZ3/latFihVeJ6/8CQQCNHWx8KLfVmpJuxNF122EFO1Pa9QtRV+R2laZH76GgsPAOw/zAt4E7u+A9OAthFf2L3oU5TzcntEgpXWAiIZXZAkEAhGFTy2ggsSc2POTpwDMFbUMzChLxbhlONjHDOI87HGyCHrJo84lY86Kzg9n2yqaFwQZ/IMhSnDRmzyOesv+6lQJABPpswVSOZ7K0R8QZv5alrZGSO785Tv1SyfwtiYwin5CeZ2bym7ndjUXrez1m6V3lO/H1sTfiMjxh71Oj+JBGwQJBAN3hUa6n5QBcc8avOCY7rV0GHNu63bDLTk8ATI3S7P31mkQYKlBtLFd1lnBsjeRb/Vwn8d6eBJ+BYXx7McFcGk0=";
            aesKey = decryptRSA(aesKey, privateKey);
            aesIv = decryptRSA(aesIv, privateKey);
            json = decryptAES(json, aesKey, aesIv);
 private String decryptRSA(String data, String key){
        try{
            //64位解码加密后的字符串
            byte[] inputByte = Base64.decodeBase64(data.getBytes("UTF-8"));
            //base64编码的私钥
            byte[] decoded = Base64.decodeBase64(key);
            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;

        }catch (Exception ex){
            ex.printStackTrace();
        }
        return data;
    }
private String decryptAES(String data, String key, String iv){
        try{
            key = AESUtil.byteArrayTransferToString(key.getBytes());
            iv = AESUtil.byteArrayTransferToString(iv.getBytes());
            data = AESUtil.decrypt(data, key, iv);
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return data;
    }

2.后台加密,前端解密

1)后台加密

package com.wonders.platform.comm.utils;

import com.wonders.common.utils.AESUtil;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/***
 * @ClassName: EncryptUtils
 * @Description: 数字信封加密工具类
 * @Auther: hu_yangyang
 * @Date: 2020/6/11 11:18
 */
public class EncryptUtils {

    //用于封装随机产生的公钥与私钥
    private static Map<Integer, String> keyMap = new HashMap<Integer, String>(2);

    /***
     * @Description:  AES和RSA结合加密
     * @Param: [json]
     * @Return: java.util.Map<java.lang.String,java.lang.String>
     */
    public static Map<String,String> encrypt(String json){
        Map<String,String> result = new HashMap<String,String>(3);
        try{
            // 生成密钥对
            genKeyPair();
            String publicKey = keyMap.get(0);
            String aesKey = randomHexString(16);
            String aesIv = randomHexString(16);
            json = encryptAES(json, aesKey, aesIv);
            aesKey = encryptRSA(aesKey, publicKey);
            aesIv = encryptRSA(aesIv, publicKey);
            result.put("json",json);
            result.put("aesKey",aesKey);
            result.put("aesIv",aesIv);
            result.put("privateKey",keyMap.get(1));
            return result;
        }catch (Exception ex){
            ex.printStackTrace();
        }
        result.put("json",json);
        return result;
    }

    /**
     * 随机生成密钥对
     * @throws NoSuchAlgorithmException
     */
    public static void genKeyPair() throws NoSuchAlgorithmException {
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器,密钥大小为96-1024位
        keyPairGen.initialize(1024,new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
        // 将公钥和私钥保存到Map
        keyMap.put(0,publicKeyString);  //0表示公钥
        keyMap.put(1,privateKeyString);  //1表示私钥
    }

    /***
     * @Description:  AES加密
     * @Param: [data, key, iv]
     * @Return: java.lang.String
     */
    public static String encryptAES(String data, String key, String iv){
        try{
            //key,可自行修改
            key = AESUtil.byteArrayTransferToString(key.getBytes());
            //偏移量,可自行修改
            iv = AESUtil.byteArrayTransferToString(iv.getBytes());
            data = AESUtil.encrypt(AESUtil.byteArrayTransferToString(data.getBytes()), key, iv);
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return data;
    }

    /**
     * 获取16进制随机数
     * @param len
     */
    public static String randomHexString(int len)  {
        try {
            StringBuffer result = new StringBuffer();
            for(int i=0;i<len;i++) {
                result.append(Integer.toHexString(new Random().nextInt(16)));
            }
            return result.toString().toUpperCase();

        } catch (Exception e) {
            e.printStackTrace();

        }
        return null;
    }

    /***
     * @Description:  RSA加密
     * @Param: [data, publicKey]
     * @Return: java.lang.String
     */
    public static String encryptRSA(String data, String publicKey) {
        try{
            //base64编码的公钥
            byte[] decoded = Base64.decodeBase64(publicKey);
            RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
            //RSA加密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            String outStr = Base64.encodeBase64String(cipher.doFinal(data.getBytes("UTF-8")));
            return outStr;

        }catch (Exception ex){
            ex.printStackTrace();
        }
        return data;
    }
}

2)前端解密

/*
 * @Author: huyangyang 
 * @Date: 2020-06-12 10:58:01 
 * @Last Modified by: huyangyang
 * @Last Modified time: 2020-07-21 14:57:25
 */

import CryptoJS from 'crypto-js'

export default {
    // 解密请求返回数据
    decryptData(privateKey,aesKey,aesIv,json){
        //RSA解密
        var jsEncrypt = new JSEncrypt();
        jsEncrypt.setPrivateKey(privateKey);
        aesKey = jsEncrypt.decrypt(aesKey);
        aesIv = jsEncrypt.decrypt(aesIv);
        //AES解密
        json = this.decrypt(json, aesKey, aesIv);
        return JSON.parse(json);
    },
    // AES解密
    decrypt(word, keyStr, ivStr) {
        var key = CryptoJS.enc.Utf8.parse(keyStr);
        var iv = CryptoJS.enc.Utf8.parse(ivStr);
        var decrypt = CryptoJS.AES.decrypt(word, key, {
            iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
        return decrypt.toString(CryptoJS.enc.Utf8);
    }
}

ps:工具类AESUtil.java
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.wonders.common.utils;

import java.security.Security;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class AESUtil {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private static final String ENCODING = "UTF-8";
    public static final String ALGORITHM_AES = "AES";
    public static final String KEY_AES = "AES";
    public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
    private static final String ECB_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    private static final String CBC_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
    public static final int CODE_BASE64 = 1;
    public static final int CODE_HEX = 2;

    public AESUtil() {
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src != null && src.length > 0) {
            for(int i = 0; i < src.length; ++i) {
                int v = src[i] & 255;
                String hv = Integer.toHexString(v);
                if (hv.length() < 2) {
                    stringBuilder.append(0);
                }

                stringBuilder.append(hv);
            }

            return stringBuilder.toString();
        } else {
            return null;
        }
    }

    public static byte[] hexStringToBytes(String hexString) {
        if (hexString != null && !hexString.equals("")) {
            hexString = hexString.toUpperCase();
            int length = hexString.length() / 2;
            char[] hexChars = hexString.toCharArray();
            byte[] d = new byte[length];

            for(int i = 0; i < length; ++i) {
                int pos = i * 2;
                d[i] = (byte)(charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
            }

            return d;
        } else {
            return null;
        }
    }

    private static byte charToByte(char c) {
        return (byte)"0123456789ABCDEF".indexOf(c);
    }

    public static String encode(String secret, String iv, String content) throws Exception {
        byte[] secretBytes = secret.getBytes();
        SecretKey secretKey = new SecretKeySpec(secretBytes, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        cipher.init(1, secretKey, ivParameterSpec);
        byte[] contentBytes = content.getBytes("UTF-8");
        byte[] bytes = cipher.doFinal(contentBytes);
        String encode = new String((new BASE64Encoder()).encode(bytes));
        return encode;
    }

    public static String decode(String secret, String iv, String content) throws Exception {
        byte[] secretKeyBytes = secret.getBytes();
        SecretKey secretKey = new SecretKeySpec(secretKeyBytes, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        cipher.init(2, secretKey, ivParameterSpec);
        byte[] contentBytes = (new BASE64Decoder()).decodeBuffer(content);
        byte[] decodeBytes = cipher.doFinal(contentBytes);
        String decode = new String(decodeBytes, "UTF-8");
        return decode;
    }

    public static String decrypt(String data, String secretKeyString, String ivString) throws Exception {
        byte[] secretKey = stringTransferToByteArray(secretKeyString);
        byte[] iv = stringTransferToByteArray(ivString);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "AES");
        cipher.init(2, secretKeySpec, new IvParameterSpec(iv));
        String result = new String(cipher.doFinal(stringTransferToByteArray(data)));
        return result;
    }

    public static String encrypt(String data, String secretKeyString, String ivString) throws Exception {
        byte[] secretKey = stringTransferToByteArray(secretKeyString);
        byte[] iv = stringTransferToByteArray(ivString);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "AES");
        cipher.init(1, secretKeySpec, new IvParameterSpec(iv));
        String result = byteArrayTransferToString(cipher.doFinal(stringTransferToByteArray(data)));
        return result;
    }

    public static String byteArrayTransferToString(byte[] bytes) {
        Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(bytes);
    }

    public static byte[] stringTransferToByteArray(String s) {
        Decoder decoder = Base64.getDecoder();
        return decoder.decode(s);
    }

    public static void main(String[] args) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128);
        byte[] secretKey = keyGenerator.generateKey().getEncoded();
        secretKey = "cc6f96c4079656ba".getBytes();
        String s = byteArrayTransferToString(secretKey);
        System.out.println("aes密钥:" + s);
        byte[] iv = "83682737f03c4212".getBytes();
        String ivString = byteArrayTransferToString(iv);
        System.out.println("aes偏移量:" + ivString);
        String str = "hello";
        String s1 = encrypt(byteArrayTransferToString(str.getBytes()), s, ivString);
        System.out.println("加密结果:" + s1);
        String s2 = decrypt(s1, s, ivString);
        System.out.println("解密结果:" + s2);
    }
}

相关文章:

  • vue2.0全局过滤器引用
  • vue2.0 多图片上传组件(el-upload)
  • json对象转map,map转list
  • 关于-webkit-的一些用法
  • CSS:字数超出两(n)行,省略号表示
  • Vant轮播多个,实现一次轮播中展示多个div,此处以三个一屏为例
  • ElementUI Tooltip 文字提示应用及更改宽度和背景色
  • vuex最详细完整的使用用法(转载)
  • vue移动端网页适配
  • 前端性能优化之Gzip打包
  • 初使用uni-app,适配多端,踩坑及经验合集
  • vscode 代码保存eslint自动格式化,最新配置:Eslint+Prettier
  • less清除浮动clearfix代码片段
  • Git使用及配置
  • Jenkins安装部署及实现CI/CD(ubuntu20.04)
  • 《Java编程思想》读书笔记-对象导论
  • 78. Subsets
  • CSS 三角实现
  • Django 博客开发教程 16 - 统计文章阅读量
  • Docker入门(二) - Dockerfile
  • JAVA之继承和多态
  • laravel with 查询列表限制条数
  • LeetCode算法系列_0891_子序列宽度之和
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • select2 取值 遍历 设置默认值
  • Service Worker
  • vue脚手架vue-cli
  • Vue学习第二天
  • webgl (原生)基础入门指南【一】
  • 百度地图API标注+时间轴组件
  • 从tcpdump抓包看TCP/IP协议
  • 多线程事务回滚
  • 开发基于以太坊智能合约的DApp
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 王永庆:技术创新改变教育未来
  • 以太坊客户端Geth命令参数详解
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • (06)金属布线——为半导体注入生命的连接
  • (LeetCode) T14. Longest Common Prefix
  • (rabbitmq的高级特性)消息可靠性
  • (八)Spring源码解析:Spring MVC
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (十八)SpringBoot之发送QQ邮件
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .NET 5种线程安全集合
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Core Web APi类库如何内嵌运行?
  • .Net Winform开发笔记(一)
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • ??myeclipse+tomcat