プログラム ape の成長に関する追加章の前後のバックエンド暗号化および復号化 (rsa+aes ハイブリッド暗号化および復号化アルゴリズム)

今年の国慶節の前夜、私は外部プロジェクトを引き継ぎ、「インターフェイス データのセキュリティを確保するためです。データ セキュリティは比較的簡単です。うーん、インターフェイスのセキュリティについては、暗号化や暗号化などの問題を考慮する必要があります。」復号化アルゴリズムとホワイトリスト。そこで、今日はインターフェイス セキュリティをテーマにした成長への道に関する特別章を立ち上げる予定です。

インターフェイスのセキュリティを考慮する理由

おそらく、コア以外のビジネス インターフェイスの作成に多くの時間と労力を費やす必要はないと思われますが、次のような質問を考えたことはありますか。私たちはいくつかのシステムを開発しています。特にパブリック システムや顧客システム (たとえば、アプレット、公式アカウントなど)、インターフェース データがハイジャックされたり、改ざんされたり、悪意を持って違法にリモートからインターフェースに呼び出されたりすると、悲惨な結果になります。現時点では、インターフェイスのセキュリティ問題を慎重に考慮する必要があります。

インターフェースのセキュリティ上の問題は何ですか?

  1. インターフェイスのアクセス権の問題。私の知る限り、ログイン アクセス権、ロール アクセス権、および動作アクセス権があります。

ログイン アクセス権限:
いわゆるログイン アクセス権限とは、認証されたユーザーのみがインターフェイスにアクセスする権利を持ち、認証されていないユーザーのアクセスは拒否されることを意味します。一般的な解決策は、ログイン アクセスの問題を一度解決する hiro および spring セキュリティ フレームワークです
。すべてのために。
一般的ではないソリューションは、aop およびインターセプターのカスタム ログイン検証サービス モジュールです。

ロールアクセス権限:
いわゆるロールアクセス権限とは、関連するロールのみがアクセス権を持ち、ユーザーのログイン認証後にロール情報を取得できることを意味します。つまり、異なるロールを持つユーザーには、ログイン後に異なるロールアクセス権限が与えられます。 。例えば、あるシステムに対してスーパー管理者と一般社員という2つの役割を設定することが可能です。
粒度の違いに応じて、ソリューションはアノテーション + AOP とインターセプターの形式に分けられます [上記 2 つのアクセス権を実現する方法、最初に穴を掘り、次の問題を埋める方法] 動作アクセス権: いわゆる動作アクセス権を指し
ます
。特定のタスクを実行する役割を制限すること。行動操作。

  1. インターフェイス データのセキュリティ問題は、受信パラメータのセキュリティ問題と戻りパラメータのセキュリティ問題に分けられます。

受信パラメータのセキュリティの問題:受信パラメータは通常、リクエスト パラメータ
を指し、通常はリクエスト本体パラメータを指します。ここで、param1 は受信パラメータの戻りパラメータです。戻りパラメータは、通常、インターフェイスによってフロント エンドに返されるパラメータを指します。ここでのデータは、このような問題を解決する最善の方法は、フロントエンドとバックエンドの暗号化と復号化を実行することです
@RequestMapping("test") public ResponseData test(@RequestBody String param1) { .... }



public ResponseData test(@RequestBody String param1) { .... }
data: {errcode:'200',data:{}, errmsg:'插入成功!'}

  1. インターフェースアクセスIPアドレスの問題

DDOS分散攻撃を防止し、プロキシアクセスを防止するため

インターフェースデータのセキュリティ問題に対する暗号化方式

  1. AES 対称暗号化 (生成されたキーの形式で暗号化と復号化、暗号化キーと復号化キーは同じ) の
    特徴: 暗号化と復号化の効率が高く、大量のデータの暗号化と復号化に適していますが、セキュリティは高くありません。高いため認証できません。
  2. RSA非対称暗号化(アルゴリズムに従って公開鍵と秘密鍵を生成、公開鍵暗号化、秘密鍵復号化)の
    特徴:暗号化と復号の効率が低い(公開鍵と秘密鍵が長く、剰余演算であるため)、暗号化と復号化に適しているデータ量の少ないコンテンツ、高いセキュリティ、認証機能付き。
  3. AES + RSA ハイブリッド暗号化 (最初に平文を AES で暗号化し、次に AES キーを RSA 公開キーで暗号化し、暗号文と RSA 暗号化キーを返す) 特徴: 方式 1 と 2 の利点を組み合わせ、より優れた方式の欠点を
    回避1と2

AES+RSAアルゴリズムの実現原理を紹介

注: rsa 公開キー暗号化、rsa 秘密キー復号化
ここに画像の説明を挿入

AES+RSA アルゴリズムのバックエンド コード

この偉人のコードから学ぶ
https://blog.csdn.net/qq_36360181/article/details/111871712
RSA 暗号化および復号化アルゴリズム コード


import com.alibaba.fastjson.JSONObject;
import com.zygswo.test1.common.exception.MyException;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * rsa 加解密工具类
 * @author 章瑜亮
 */
@Slf4j
public class RsaEncryptUtil<T> {
    
    
    /**
     * 加密算法
     */
    private static final String ALGO_NAME = "RSA";
    /**
     * RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024
     */
    public static final int KEY_SIZE = 2048;
    /**
     * 算法默认为RSA/NONE/PKCS1Padding,未验证
     */
    public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";

    /**
     * 加密请求返回对象的公钥
     */
    private static final String PUBLIC_KEY = "";
    /**
     * 解密请求返回对象的私钥(放在配置文件中)
     */
   private static final String PRIVATE_KEY = "";

    /**
     * 注意只能生成一次
     * @return 私钥公钥密钥对
     */
    private static Map<String,String> generateKeyPairs() {
    
    
        try {
    
    
            KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGO_NAME);
            generator.initialize(KEY_SIZE);  //rsa长度
            KeyPair keyPair = generator.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            Map<String, String> map = new ConcurrentHashMap<>();
            map.put("public_key", Base64.getEncoder().encodeToString(publicKey.getEncoded()));
            map.put("private_key",Base64.getEncoder().encodeToString(privateKey.getEncoded()));
            return map;
        } catch (NoSuchAlgorithmException e) {
    
    
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return null;
    }

    /**
     * 给AES密钥解密,再调用AES解密
     * @param privatekey 解密用的rsa私钥
     * @param encodedText 密文
     * @param aesKeyEncrypt rsa加密后的AES密钥
     * @return 解密后的明文
     */
    public static String decryptionRsaAndAes(String privatekey, String encodedText,String aesKeyEncrypt){
    
    
        // 解密
        String aesKeyDecrypt = decodeString(privatekey, aesKeyEncrypt);
        //解密后aes密钥
        String data = AesEncryptUtil.decryptStringBySecret(encodedText, aesKeyDecrypt);
        return data;
    }

    /**
     * 调用AES加密明文(JSON OBJECT),再用RSA算法加密AES密钥
     * @param data 明文
     * @return 解密后的明文
     */
    public static <T> Map<String, String> encryptionRsaAndAes(T data) {
    
    
        //加密明文
        log.info("-------------------data=" + JSONObject.toJSONString(data) + "---------------------");
        String encodedText = AesEncryptUtil.encryptString(JSONObject.toJSONString(data), AesEncryptUtil.SYMMETRY_ENCRYPT.AES);
        log.info("-------------------encodedText=" + encodedText + "---------------------");
        // 加密后aes密钥
        String aesKeyEncrypt = encodeString(PUBLIC_KEY, AesEncryptUtil.DEFAULT_SECRET);
        //解密后aes密钥
        Map<String, String> map = new ConcurrentHashMap<>();
        map.put("encodedText", encodedText);
        map.put("aesKeyEncrypt",aesKeyEncrypt);
        return map;
    }

    /**
     * 生成公私钥的算法(只生成一次)
     * @param args 参数
     */
//    public static void main(String[] args) {
    
    
//        Map<String,String> keyPairs = generateKeyPairs();
//        String publicKey = keyPairs.get("public_key");
//        String privateKey = keyPairs.get("private_key");
//        log.info("----------------publicKey = " + publicKey + "-------------------");
//        log.info("----------------privateKey = " + privateKey + "-------------------");
//        String encodedStr = encodeString(publicKey, "123456");
//        log.info("----------------base64Str = " + encodedStr + "-------------------");
//        String result = decodeString(privateKey, encodedStr);
//        log.info("----------------final result = " + result + "-------------------");
//    }

    /**
     * 加密算法
     * @param needEncodeText 需要加密的字符串
     * @param publicKey 加密密钥(公钥)
     */
    private static String encodeString(String publicKey, String needEncodeText) {
    
    
        try {
    
    
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            //将字符串转PublicKey对象
            // bytes 为base64处理后的字节码,所以要先base64Encoder一下
            byte[] data = Base64.getDecoder().decode(publicKey.getBytes());
            X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
            KeyFactory fact = KeyFactory.getInstance(ALGO_NAME);
            PublicKey publicKey1 = fact.generatePublic(spec);
            //初始化加密工具
            cipher.init(Cipher.ENCRYPT_MODE, publicKey1);
            //将需要加密的字串转字节码
            byte[] bytes = needEncodeText.getBytes();
            // 加密
            byte[] resultBytes = cipher.doFinal(bytes);
            //转base64(不清楚是否需要判断为空)
            return Base64.getEncoder().encodeToString(resultBytes);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeySpecException |
                InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
    
    
            e.printStackTrace();
            log.error(e.getMessage());
            throw new MyException(e.getMessage());
        }
    }

    /**
     * 解密算法
     * @param needDecodeText 需要解密的字符串
     * @param privateKey 解密密钥(私钥)
     */
    private static String decodeString(String privateKey, String needDecodeText) {
    
    
        try {
    
    
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            //将字符串转PublicKey对象
            // bytes 为base64处理后的字节码,所以要先base64Encoder一下
            byte[] data = Base64.getDecoder().decode(privateKey.getBytes());
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(data);
            KeyFactory fact = KeyFactory.getInstance(ALGO_NAME);
            PrivateKey privateKey1 = fact.generatePrivate(spec);
            //初始化加密工具
            cipher.init(Cipher.DECRYPT_MODE, privateKey1);
            //将需要加密的字串转字节码
            //base64转byte
            byte[] bytes = Base64.getDecoder().decode(needDecodeText.getBytes());
            // 解密
            byte[] resultBytes = cipher.doFinal(bytes);
            return resultBytes == null ? null : new String(resultBytes);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            log.error(e.getMessage());
            throw new MyException("解密失败,请检查加解密密钥");
        }
    }
}

AES暗号化および復号化アルゴリズムコード


import com.zygswo.test1.common.exception.MyException;
import lombok.extern.slf4j.Slf4j;


import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;

/**
 * aes加密
 */
@Slf4j
public class AesEncryptUtil {
    
    
        //DES算法要有一个随机数源,因为Random是根据时间戳生成的有限随机数,比较容易破解,所以在这里使用SecureRandom
        private static SecureRandom secureRandom = new SecureRandom();
        //AES默认加密key, 长度固定为16位,代表128bit的密钥
        static final String DEFAULT_SECRET = "自定义加密key";
        //字符集
        private static final String CHARSET = "UTF-8";

        /**
         * 功能描述: <br>
         * 〈字符串解密〉<密钥参数>
         */
        public static String decryptStringBySecret(String source, String secret) {
    
    
            try {
    
    
                byte[] sourceBytes = Base64.getDecoder().decode(source);
                byte[] secretBytes = secret.getBytes(CHARSET);
                byte[] encryptBytes = decrypt(sourceBytes, secretBytes, SYMMETRY_ENCRYPT.AES);
                return new String(encryptBytes, CHARSET);
            } catch (Exception e) {
    
    
                e.printStackTrace();
                throw new MyException("解密失败,请检查加解密密钥");
            }
        }

        /**
         * 功能描述: <br>
         * @param source 要加密的文本
         * @param encryptType 加密类型(AES,DES)
         * 〈字符串加密〉
         */
        public static String encryptString(String source, SYMMETRY_ENCRYPT encryptType) {
    
    
            try {
    
    
                byte[] sourceBytes = source.getBytes(CHARSET);
                byte[] secretBytes = DEFAULT_SECRET.getBytes(CHARSET);
                byte[] encryptBytes = encrypt(sourceBytes, secretBytes, encryptType);
                return Base64.getEncoder().encodeToString(encryptBytes);
            } catch (InvalidKeyException | NoSuchAlgorithmException | UnsupportedEncodingException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException e) {
    
    
                e.printStackTrace();
                throw new MyException(e.getMessage());
            }
        }

        /**
         * 功能描述: <br>
         * 〈字符串解密〉
         */
        public static String decryptString(String source, SYMMETRY_ENCRYPT encryptType) {
    
    
            try {
    
    
                byte[] sourceBytes = Base64.getDecoder().decode(source);
                byte[] secretBytes = DEFAULT_SECRET.getBytes(CHARSET);
                byte[] encryptBytes = decrypt(sourceBytes, secretBytes, encryptType);
                return new String(encryptBytes, CHARSET);
            } catch (InvalidKeyException | NoSuchAlgorithmException | UnsupportedEncodingException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException e) {
    
    
                e.printStackTrace();
                throw new MyException(e.getMessage());
            }
        }

        /**
         * 功能描述: <br>
         * 〈使用原始密钥数据转换为SecretKey对象〉
         */
        private static SecretKey getSecretKey(byte[] keyBytes, String type) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
    
    
            if ("DES".equals(type)) {
    
    
                // 创建一个密匙工厂
                SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(type);
                // 创建一个DESKeySpec对象
                DESKeySpec dks = new DESKeySpec(keyBytes);
                // 将DESKeySpec对象转换成SecretKey对象
                return keyFactory.generateSecret(dks);
            }
            return new SecretKeySpec(keyBytes, type);
        }

        /**
         * 功能描述: <br>
         * 〈DES加密〉
         */
        private static byte[] encrypt(byte[] contentArray, byte[] keyArray, SYMMETRY_ENCRYPT encryptType) throws InvalidKeyException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeySpecException {
    
    
            return symmetryDE(contentArray, keyArray, Cipher.ENCRYPT_MODE, encryptType);
        }

        /**
         * 功能描述: <br>
         * 〈DES解密〉
         */
        private static byte[] decrypt(byte[] encryptArray, byte[] keyArray, SYMMETRY_ENCRYPT encryptType) throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
    
    
            return symmetryDE(encryptArray, keyArray, Cipher.DECRYPT_MODE, encryptType);
        }

        /**
         * 功能描述: <br>
         * 〈Cipher 加密解密操作〉
         */
        private static byte[] symmetryDE(byte[] contentArray, byte[] keyArray, int mode, SYMMETRY_ENCRYPT encryptType) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidKeySpecException {
    
    
            //获取密钥对象
            SecretKey secretKey = getSecretKey(keyArray, encryptType.getType());
            //获取真正执行加/解密操作的Cipher
            Cipher cipher = Cipher.getInstance(encryptType.getEncrypt());
            //用密匙初始化Cipher对象
            cipher.init(mode, secretKey, secureRandom);
            //执行加/解密操作
            return cipher.doFinal(contentArray);
        }

        /**
         * 功能描述: <br>
         * 〈加密方式〉
         *
         * @author Blare
         * @date 2019/12/11
         */
        enum SYMMETRY_ENCRYPT {
    
    
            AES("AES", "AES/ECB/PKCS5Padding"),
            DES("DES", "DES/ECB/PKCS5Padding");

            SYMMETRY_ENCRYPT(String type, String encrypt) {
    
    
                this.type = type;
                this.encrypt = encrypt;
            }

            private String type;
            private String encrypt;

            public String getType() {
    
    
                return type;
            }

            public String getEncrypt() {
    
    
                return encrypt;
            }
        }
}

予防

以前インターセプターを使用してインターフェイスの受信パラメータを復号化しようとしましたが、インターセプターはdispatcherServletの後、コントローラーを呼び出す前に動作するため、@RequestBodyアノテーションと一緒に使用するとSteamクローズ例外を報告することがわかりました。フィルターを使用して対処します。

フィルターコード:

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 过滤器
 * @author 章瑜亮
 */
@Component
@Slf4j
@WebFilter(filterName = "requestBodyFilter", urlPatterns = "/*", asyncSupported = true)
public class RequestBodyFilter implements Filter {
    
    

    @Override
    public void destroy() {
    
    

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)  throws ServletException, IOException{
    
    
        //获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中。
        // 在chain.doFiler方法中传递新的request对象
        ServletRequest requestWrapper = null;
        if(request instanceof HttpServletRequest) {
    
    
            requestWrapper = new RequestWrapper((HttpServletRequest) request);
        }
        if(requestWrapper == null) {
    
    
            chain.doFilter(request, response);
        } else {
    
    
            chain.doFilter(requestWrapper, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    
    

    }
}

また、リクエストが一度しか取得できない状況を解決するために、HttpServletRequestWrapper クラスが実装されており、コードは
次のとおりです。

import com.alibaba.fastjson.JSONObject;
import com.zygswo.test1.common.exception.MyException;
import com.zygswo.test1.common.util.RsaEncryptUtil;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

/**
 * 确保request可以多次读取
 * @author 章瑜亮
 */
@Slf4j
public class RequestWrapper extends HttpServletRequestWrapper {
    
    
    /**
     * 私钥
     */
    private String privateKey = "";

    /**
     * 请求体
     */
    private byte[] body;

    public RequestWrapper(HttpServletRequest request) {
    
    
        super(request);
        // 获取requestbody中的数据
        body = getBodyString(request);
    }

    @Override
    public BufferedReader getReader() throws IOException {
    
    
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
    
    
        // 定义内存中的输入流
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {
    
    

            @Override
            public int read() throws IOException {
    
    
                // 使用内存输入流读取数据
                return bais.read();
            }

            @Override
            public boolean isFinished() {
    
    
                return false;
            }

            @Override
            public boolean isReady() {
    
    
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
    
    

            }
        };
    }

    /**
     * 永久获取request请求头并进行请求体参数处理
     * @param request
     * @return
     */
    private byte[] getBodyString(HttpServletRequest request)  {
    
    
        try (BufferedInputStream bis = new BufferedInputStream(request.getInputStream());
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
    
    
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) > 0) {
    
    
                baos.write(buffer, 0, len);
            }
            byte[] bytes= baos.toByteArray();
            String body = new String(bytes);
            log.info("------------------- body = " + body + "------------------------");
            if (isNotBlank(body)) {
    
    
                JSONObject jsonBody = JSONObject.parseObject(body);
                if (null != jsonBody) {
    
    
                    String aesKey = request.getHeader("token");
                    String dataEncrypt = jsonBody.getString("data");
                    String data;
                    JSONObject json = null;
                    try {
    
    
                        log.info("------------------- dataEncrypt = " + dataEncrypt + "------------------------");
                        log.info("------------------- aesKey = " + aesKey + "------------------------");
                        data = RsaEncryptUtil.decryptionRsaAndAes(privateKey, dataEncrypt, aesKey);
                        // 如果数据不为空就编译
                        if (isNotBlank(data)) {
    
    
                            //如果参数为空前端传回undefined
                            if ("undefined".equalsIgnoreCase(data)) {
    
    
                                json = new JSONObject();
                            } else {
    
    
                                json = JSONObject.parseObject(data);
                            }
                        }
                    } catch (Exception e) {
    
    
                        log.error(e.getMessage());
                        e.printStackTrace();
                        throw new MyException("解密失败,请检查加解密密钥");
                    }
                    if (json != null) {
    
    
                        body = json.toJSONString();
                    }
                    log.info("------------------- body = " + body + "------------------------");
                    return body.getBytes();
                }
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
            log.error(e.getMessage());
            throw new MyException("解密失败,请检查加解密密钥");
        }
        return null;
    }

    /**
     * 判断字符串是否为空
     * @param string 字符串
     * @return 是否为空
     */
    private boolean isNotBlank(String string) {
    
    
        return string != null && !"".equals(string);
    }
}


最後にフィルターを登録するだけで使用できるようになります。

フロントエンドコードの実装

準備:

  1. npm ダウンロード Crypto.js npm インストール crypto-js
  2. npm ダウンロード jsencrypt.min.js
import CryptoJS, {
    
     enc } from "crypto-js";
import JSEncrypt from './jsencrypt.min.js'

export default {
    
    
	
	// AES密钥(加密前)
	aesKey : '',
	// AES密钥(加密后)
    aesKeyEncrypt: '',
	
	/**
	  * rsa + aes加密
	  *@param word:需要加密的内容
	  *@returns {*} :返回加密的内容
	  */
	 encryptFun:function(word) {
    
    
	    //初始化AES密钥
	    this.aesKey = this.get32RandomNum();
	    //加密AES密钥
	    var encrypt = new JSEncrypt();
		console.log(publicKey);
	    encrypt.setPublicKey(publicKey);
	    this.aesKeyEncrypt = encrypt.encrypt(this.aesKey);
	
	    //AES加密密钥
	    var key = CryptoJS.enc.Utf8.parse(this.aesKey);
	    //AES加密内容
	    var srcs = CryptoJS.enc.Utf8.parse(word);
	    //AES加密
	    var encrypted =CryptoJS.AES.encrypt(srcs, key, {
    
     mode: CryptoJS.mode.ECB, padding:CryptoJS.pad.Pkcs7 });
	    //返回
	    return encrypted.toString();
	},
	
	/**
	  * rsa + aes解密
	  *@param encodedText:需要解密的内容
	  *@returns {*} :返回解密的内容
	  */
	 decryptFun:function(encodedText) {
    
    
	    //获取参数
	    var resultObj = JSON.parse(encodedText);
		//获取加密后的aeskey 和内容
		var aesKeyEncrypt = resultObj['aesKeyEncrypt'];
		var encodedText = resultObj['encodedText'];
		console.log("解密前密文 ===> " + encodedText);

	    //解密AES密钥
	    var decrypt = new JSEncrypt();
		console.log(privateKey);
	    decrypt.setPrivateKey(privateKey);
	    var aesKey = decrypt.decrypt(aesKeyEncrypt);
	    console.log("解密后AES密钥 ===> " + aesKey);
	
	    //AES解密密钥
	    var key = CryptoJS.enc.Utf8.parse(aesKey);
	    //AES解密
	    var decrypted = CryptoJS.AES.decrypt(encodedText, key, {
    
    
			mode: CryptoJS.mode.ECB,
			padding: CryptoJS.pad.Pkcs7
		});
	    //返回
		console.log("解密后密文 ===> " + CryptoJS.enc.Utf8.stringify(decrypted).toString());
	    var result=CryptoJS.enc.Utf8.stringify(decrypted).toString();
		return JSON.parse(result);
	},
	
	/**
	 * 加密参数
	 * @param data
	 * @returns {string}
	 */
	getEncryptData: function(data) {
    
    
	    return JSON.stringify({
    
    "data":this.encryptFun(JSON.stringify(data))});
	},
	
	/**
	 * 获取32位随机码
	 * @returns {string}
	 */
	get32RandomNum: function(){
    
    
	    var chars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
	    var nums="";
	    for(var i=0;i<32;i++){
    
    
	        var id = parseInt(Math.random()*61);
	        nums+=chars[id];
	    }
	    return nums;
	},
	
	/**
	 * 判断url是否在验证白名单中
	 * @param url
	 */
	verifyWhiteList: function(url) {
    
    
	    var whiteList = ["/login"];
	    for (var i = 0;i < whiteList.length;i++){
    
    
	        if(url.indexOf(whiteList[i]) != -1){
    
    
	            return true;
	        }
	    }
	    return false;
	},
	
	/**
	 * rsa加密
	 */
	rasEncrypt: function() {
    
    
	    var encrypt = new JSEncrypt();
	    encrypt.setPublicKey(this.publicKey);
	    // 这里输出加密后的字符串
	    console.log(encrypt.encrypt("你好asd1"));
	},
	
	/**
	  * aes加密
	  *@param word:需要加密的内容
	  *@returns {*} :返回加密的内容
	  */
	encrypt: function(word) {
    
    
	    varkey = CryptoJS.enc.Utf8.parse("abcdefgabcdefg12");
	    var srcs =CryptoJS.enc.Utf8.parse(word);
	    var encrypted =CryptoJS.AES.encrypt(srcs, key, {
    
     mode: CryptoJS.mode.ECB, padding:CryptoJS.pad.Pkcs7 });
	    return encrypted.toString();
	},
	
	/**
	  * aes解密
	  * @param word
	  * @returns {*}
	  */
	decrypt: function(word) {
    
    
	    var key =CryptoJS.enc.Utf8.parse("abcdefgabcdefg12");
	    var decrypt =CryptoJS.AES.decrypt(word, key, {
    
     mode: CryptoJS.mode.ECB, padding:CryptoJS.pad.Pkcs7 });
	    returnCryptoJS.enc.Utf8.stringify(decrypt).toString();
	}
}

最後に書きます

注意が必要な別の問題があります。つまり、jre 環境のセキュリティ パッケージは、256 ビット キーの暗号化と復号化を可能にするために 2 つの jar パッケージ local_policy.jar と US_export_policy.jar を変更する必要があります。

たくさんの落とし穴を踏んだ後、ようやく完成し、ようやく実現したスクリーンショットを貼り付けました
画像の説明を追加してください

おすすめ

転載: blog.csdn.net/qq_31236027/article/details/127176084
おすすめ