Js und Java verwenden CryptoJS.pad.Pkcs7, AES/CBC/PKCS7Padding, um Datenverschlüsselung und -entschlüsselung zu realisieren (crypto-js, bouncycastle, hutool-java)

        In letzter Zeit ist die Entwicklung auf die Notwendigkeit einer Docking-Schnittstelle gestoßen, und diese Schnittstelle wird direkt vom Front-End Ajax aufgerufen. Es gibt Verschlüsselungs- und Entschlüsselungsprozesse vor und nach der Schnittstelle. CryptoJS wird verwendet, und der Verschlüsselungsmodus ist: padding: CryptoJS.pad.Pkcs7

Die Front-End-Verschlüsselungsmethode ist

Voranfrageskript:

var reqeust_data = 
{ 
    "data": {
                   "你的参数1": "***",
                   "你的参数2": "***", 
                   "你的参数3": "***" 
            },
    "req_time":Date.parse(new Date()), // 请求时间戳
    "request_string":randomString(32), // 32位随机字符串
}
var aes_key = pm.request.getHeaders().AES_KEY;
console.log("传入参数 -> " + JSON.stringify(reqeust_data));
var en_reqdata = AES_CBC_encrypt(JSON.stringify(reqeust_data), aes_key);
pm.environment.set("params",en_reqdata);   // {
   
   {params}} 为接口传入body的参数

//Generate 32-bit random string
function randomString(len) {
    len = len || 32;
    var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';   
    var maxPos = $chars.length;
    var random_str = '';
    for (i = 0; i < len; i++) {
      pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return random_str;
 }

//aes encode
function AES_CBC_encrypt(message, key) {
    let keyHex = CryptoJS.enc.Hex.parse(key); //
    let ivHex = CryptoJS.enc.Utf8.parse("0000000000000000");
    let messageHex = CryptoJS.enc.Utf8.parse(message);
    let encrypted = CryptoJS.AES.encrypt(messageHex, keyHex, {
        iv: ivHex,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    return encrypted.toString();
}

//aes decode
function decrypt(word, keyStr){
  //console.log('decrypt key:' + keyStr);
  let keyHex = CryptoJS.enc.Hex.parse(keyStr); //
  let ivHex = CryptoJS.enc.Utf8.parse("0000000000000000");
  let base64 = CryptoJS.enc.Base64.parse(word);
  let src =  CryptoJS.enc.Base64.stringify(base64);
  var decrypt = CryptoJS.AES.decrypt(src, keyHex, 
  {
       iv:  ivHex,
       mode:CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7
  });
  return decrypt.toString(CryptoJS.enc.Utf8);
}

Entschlüsseltes Js-Skript nach Anfrage

Tests:

var aes_key = pm.request.getHeaders().AES_KEY;
var result = decrypt(responseBody, aes_key);
console.log("返回信息明文 -> " + result);

//aes decode
function decrypt(word, keyStr){
  //console.log('decrypt key:' + keyStr);
  let keyHex = CryptoJS.enc.Hex.parse(keyStr); //
  let ivHex = CryptoJS.enc.Utf8.parse("0000000000000000");
  let base64 = CryptoJS.enc.Base64.parse(word);
  let src =  CryptoJS.enc.Base64.stringify(base64);
  var decrypt = CryptoJS.AES.decrypt(src, keyHex, 
  {
       iv:  ivHex,
       mode:CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7
  });
  return decrypt.toString(CryptoJS.enc.Utf8);
}

        Wenn wir also jetzt Java verwenden müssen, um diese Verschlüsselung zu implementieren und dann die Schnittstelle anzufordern, können wir zuerst eine Tool-Klasse mit Hutool implementieren, damit wir sie aufrufen können. Aber für CryptoJS in Js, Padding: CryptoJS.pad.Pkcs7, der Standardmodus, der AES in Java entspricht, ist: AES/ECB/PKCS7Padding. Und es kommt vor, dass die Aufzählungsklasse von Hutool diesen Modus nicht hat:

 In Hutools Ausgabe hat gerade jemand diese Frage gestellt, und der ursprüngliche Autor hat auch geantwortet

 Hutool allein verfügt nicht über diesen Verschlüsselungsalgorithmus, daher muss es mit der BC-Bibliothek zusammenarbeiten, um ihn zu verwenden

Zuerst müssen Sie die BC-Bibliothek in Maven importieren:

<dependency> 
    <groupId>org.bouncycastle</groupId> 
    <artifactId>bcprov-jdk15on</artifactId> 
    <version>1.68</version> 
</dependency> 

Pakete in der Java Standard Library java.securitybieten einen Standardmechanismus, der eine nahtlose Integration durch Drittanbieter ermöglicht. Wenn wir den von BouncyCastle bereitgestellten AES/ECB/PKCS7Padding-Algorithmus verwenden möchten, müssen wir BouncyCastle zuerst registrieren (einige brauchen es, andere nicht, führen Sie es einfach aus):

Unter ihnen wird die Registrierung von BouncyCastle durch die folgende Erklärung realisiert:

Security.addProvider(new BouncyCastleProvider());

 Beginnen Sie dann mit dem Schreiben unserer Klasse für Verschlüsselungstools

package com.psds.credit.data.utils;

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.symmetric.AES;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * @author JMzz
 * @description
 */
@Slf4j
public class AESUtil {

    private static String AES_KEY = "你的密钥";

    private static final String IV_KEY = "0000000000000000";


    public static String encrypt(String message, String key, Mode mode, String padding) {
        byte[] baseKey = null;
        if (StringUtils.isNotEmpty(key)) {
            baseKey = HexUtil.decodeHex(key);
        } else {
            baseKey = HexUtil.decodeHex(AES_KEY);
        }
        byte[] ivBytes = IV_KEY.getBytes(StandardCharsets.UTF_8);
        byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
        AES aes = new AES(mode.name(), padding, baseKey, ivBytes);
        return new Base64().encodeAsString(aes.encrypt(messageBytes));
    }

    public static String decrypt(String message, String key, Mode mode, String padding) {
        byte[] baseKey = null;
        if (StringUtils.isNotEmpty(key)) {
            baseKey = HexUtil.decodeHex(key);
        } else {
            baseKey = HexUtil.decodeHex(AES_KEY);
        }
        byte[] ivBytes = IV_KEY.getBytes(StandardCharsets.UTF_8);
        AES aes = new AES(mode.name(), padding, baseKey, ivBytes);
        return aes.decryptStr(message);
    }


    // 不用HexUtil.decodeHex,也可以这个方法
    private static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }


    public static String randomString(int len) {
        len = len > 0 ? len : 32;
        String chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
        int maxPos = chars.length();
        StringBuilder pwd = new StringBuilder();
        for (int i = 0; i < len; i++) {
            pwd.append(chars.charAt((int) (Math.random() * maxPos)));
        }
        return pwd.toString();
    }


}

Verwenden Sie zum Entschlüsseln einfach die erhaltene response.body() zum Entschlüsseln.

Zum Unterschied zwischen AES/CBC/PKCS7Padding und AES/CBC/PKCS5Padding:

        PKCS5Padding ist eine Teilmenge von PKCS7Padding. Es versteht sich, dass PKCS5Padding ein bestimmter Block von PKCS7Padding ist. Die PKCS5Padding-Implementierung von JDK wird gemäß dem PKCS7Padding-Standard implementiert, sodass es keinen Unterschied zwischen der Verwendung von PKCS5Padding und PKCS7Padding beim Erstellen von Cipher in Java gibt.

Supongo que te gusta

Origin blog.csdn.net/weixin_45740811/article/details/129322049
Recomendado
Clasificación