Untitled

 avatar
unknown
java
8 months ago
3.9 kB
3
Indexable
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.json.JSONUtil;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Map;
import java.util.TreeMap;

public class EncryptionExample {

    private static class AesUtils {
        public byte[] getRandomKey(int length) {
            byte[] key = new byte[length];
            new SecureRandom().nextBytes(key);
            return key;
        }

        public String encrypt(String raw, byte[] key, byte[] iv) {
            AES aes = SecureUtil.aes(key);
            aes.setIv(iv);
            return Base64.getEncoder().encodeToString(aes.encrypt(raw));
        }

        private String pad(String text) {
            int blockSize = 16;
            int padding = blockSize - (text.length() % blockSize);
            char padChar = (char) padding;
            return text + String.valueOf(padChar).repeat(padding);
        }
    }

    private static class RsaUtils {
        private final RSA rsa;

        public RsaUtils(String publicKey, String privateKey) {
            rsa = new RSA(privateKey, publicKey);
        }

        public String rsaEncrypt(byte[] data) {
            byte[] encryptedData = rsa.encrypt(data, KeyType.PublicKey);
            return Base64.getEncoder().encodeToString(encryptedData);
        }

        public String sign(String privateKey, byte[] data) {
            RSA signer = new RSA(privateKey, null);
            byte[] signature = signer.sign(data);
            return Base64.getEncoder().encodeToString(signature);
        }
    }

    public static String spliceSignText(Map<String, String> info) {
        TreeMap<String, String> sortedMap = new TreeMap<>(info);
        StringBuilder signText = new StringBuilder();
        sortedMap.forEach((key, value) -> signText.append(key).append("=").append(value).append("&"));
        signText.deleteCharAt(signText.length() - 1); // Remove trailing "&"
        return signText.toString();
    }

    public static void main(String[] args) {
        // 加密工具实例
        AesUtils aesUtils = new AesUtils();
        RsaUtils rsaUtils = new RsaUtils(publicKey, privateKey);

        String merchantNumber = "ET82009";
        String subMerchantNumber = "ET82009S001";

        // 数据组装
        Map<String, String> requestData = new TreeMap<>();
        requestData.put("merchant_number", merchantNumber);
        requestData.put("sub_merchant_number", subMerchantNumber);
        requestData.put("version", "3.1.0");

        // 生成 AES Key
        byte[] aesKey = aesUtils.getRandomKey(16);
        String aesKeyCipher = rsaUtils.rsaEncrypt(aesKey);
        requestData.put("aeskey", aesKeyCipher);

        // 加密敏感数据
        String sensitiveData = JSONUtil.toJsonStr(new SensitiveData());
        String encryptedSensitiveData = aesUtils.encrypt(sensitiveData, aesKey, new byte[16]);
        requestData.put("sensitive_data", encryptedSensitiveData);

        // 签名数据
        String signText = spliceSignText(requestData);
        String signature = rsaUtils.sign(privateKey, signText.getBytes(StandardCharsets.UTF_8));
        requestData.put("sign", signature);

        // 发送API请求(代码略)
    }

    private static class SensitiveData {
        public String institutionCode = "GEA0250";
        public String apartmentName = "爱情公寓";
        public String merchantOrderId = "订单编号";
        public String merchantUserKey = "用户编号";
        public String countryCode = "USA";
        public String currencyCode = "USD";
        public String sourceCountryCode = "CHN";
        public int priceMode = 1;
        public int tuition = 10000;
    }
}
Editor is loading...
Leave a Comment