package com.stm.asset.utils;


import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;

/**
 * SM2国密工具类
 * @author LIULEI 
 */
public class SM2Util {
    private final static String publicKey = "043aa5e5b9b5f4f74596e964359ac229c3f6fe0ec651b46406d42b345984b6abc1d0abbe82618a8dd56df08b0e9b7fd1a363e492ff3e24f140a7d1ced1f1aa9f20";
    private final static String publicQKey = "043aa5e5b9b5f4f74596e964359ac229c3f6fe0ec651b46406d42b345984b6abc1d0abbe82618a8dd56df08b0e9b7fd1a363e492ff3e24f140a7d1ced1f1aa9f20";
    private final static String privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgoy5Dj/P5Dw+xhkPLz7riyylgBOkUDKmxfb0a4PzVCgigCgYIKoEcz1UBgi2hRANCAAQ6peW5tfT3RZbpZDWawinD9v4OxlG0ZAbUKzRZhLarwdCrvoJhio3VbfCLDpt/0aNj5JL/PiTxQKfRztHxqp8g";
    
    public static void getSm2KeyPair() {
        SM2 sm2 = SmUtil.sm2();
        
        /* 公钥 */
        String publicKey = sm2.getPublicKeyBase64();
        System.out.println("publicKey>>【" + publicKey + "】");
        /* js端公钥 JS代码实现 SM2的方案，都是直接使用的私钥的d值和公钥的q值直接进行的加解密，所以后端返回的最好是从公钥里面提取的q值，以q值作为js端的加密公钥 */
        String publicQKey = HexUtil.encodeHexStr(((BCECPublicKey)sm2.getPublicKey()).getQ().getEncoded(false));
        System.out.println("publicQKey>>【" + publicQKey + "】");
        /* 私钥 */
        String privateKey = sm2.getPrivateKeyBase64();
        System.out.println("privateKey>>【" + privateKey + "】");
    }

    /**
     * 公钥加密
     * @param data
     * @param publicKey
     * @return
     */
    public static String encrypt(String data, String publicKey) {
        SM2 sm2 = SmUtil.sm2(null, publicKey);
        String encryptStr = sm2.encryptBcd(data, KeyType.PublicKey);
        return encryptStr;
    }

    /**
     * 公钥加密
     * @param data
     * @return
     */
    public static String encrypt(String data) {
        return encrypt(data, publicKey);
    }

    /**
     * 私钥解密 公钥加密密文
     * @param encryptStr
     * @param privateKey
     * @return
     */
    public static String decrypt(String encryptStr, String privateKey) {
        if (!encryptStr.startsWith("04")) {
            encryptStr = "04".concat(encryptStr);
        }
        SM2 sm2 = SmUtil.sm2(privateKey, null);
        String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));
        return decryptStr;
    }

    /**
     * 私钥解密 公钥加密密文
     * @param encryptStr
     * @return
     */
    public static String decrypt(String encryptStr) {
        return decrypt(encryptStr, privateKey);
    }
    
    public static void main(String[] args) {
        getSm2KeyPair();
    }
}
