package cn.gintone.encryptionUtils;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.jce.interfaces.ECPrivateKey;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.math.ec.ECPoint;

import java.security.*;
import java.security.spec.*;
import java.util.Base64;

public class SM2KeyUtils {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    // 公钥对象转字符串 (Base64)
    public static String publicKeyToString(PublicKey publicKey) {
        if (publicKey == null) return null;
        ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
        byte[] keyBytes = ecPublicKey.getQ().getEncoded(true); // 压缩格式
        return Base64.getEncoder().encodeToString(keyBytes);
    }

    // 字符串转公钥对象
    public static PublicKey stringToPublicKey(String publicKeyStr) throws Exception {
        if (publicKeyStr == null || publicKeyStr.isEmpty()) return null;
        byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);
        ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("sm2p256v1");
        ECPoint ecPoint = ecSpec.getCurve().decodePoint(keyBytes);
        ECPublicKeySpec keySpec = new ECPublicKeySpec(ecPoint, ecSpec);
        return KeyFactory.getInstance("EC", "BC").generatePublic(keySpec);
    }

    // 私钥对象转字符串 (Base64)
    public static String privateKeyToString(PrivateKey privateKey) {
        if (privateKey == null) return null;
        ECPrivateKey ecPrivateKey = (ECPrivateKey) privateKey;
        byte[] keyBytes = ecPrivateKey.getD().toByteArray(); // 大整数字节
        return Base64.getEncoder().encodeToString(keyBytes);
    }

    // 字符串转私钥对象
    public static PrivateKey stringToPrivateKey(String privateKeyStr) throws Exception {
        if (privateKeyStr == null || privateKeyStr.isEmpty()) return null;
        byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);
        ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("sm2p256v1");
        ECPrivateKeySpec keySpec = new ECPrivateKeySpec(new java.math.BigInteger(1, keyBytes), ecSpec);
        return KeyFactory.getInstance("EC", "BC").generatePrivate(keySpec);
    }
}
