package org.tio.sitexxx.service.service.pay.utils.ncount;

import org.tio.sitexxx.service.service.pay.exception.NCountException;
import org.tio.sitexxx.service.service.pay.utils.HexStringByte;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

/**
 * <pre>
 *    @author : vagrancy
 *    e-mail : 18050829067@163.com
 *    time   : 2025-11-26 11:39
 *    desc   :
 * </pre>
 */
public class NCountRSAAlgorithms {

    /**
     * @param publicKey
     *            公钥HEX字符串
     * @return 返回公钥
     * @throws Exception
     */
    public static PublicKey getPublicKey(String publicKey) throws NCountException {
        PublicKey pubKey;
        try {
            byte[] encodedKey = HexStringByte.hexToByte(publicKey.getBytes());
            KeyFactory keyFactory = KeyFactory.getInstance(NCountKey.ALGORITHM);
            pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
        } catch (InvalidKeySpecException e) {
            throw new NCountException("公钥无效!", e);
        } catch (NoSuchAlgorithmException e) {
            throw new NCountException("算法类型无效!", e);
        }
        return pubKey;
    }

    /**
     * @param priKey
     *            私钥
     * @param data
     *            要签名的数据
     * @return 签名消息
     * @throws Exception
     */
    public static byte[] sign(PrivateKey priKey, String data) throws NCountException {
        try {
            Signature signet = Signature.getInstance(NCountKey.SIGN_ALGORITHM);
            signet.initSign(priKey);
            signet.update(data.getBytes(StandardCharsets.UTF_8));
            return signet.sign();
        } catch (Exception e) {
            throw new NCountException(e.getMessage());
        }
    }

    /**
     * 验证签名
     *
     * @param publicKey
     *            公钥HEX字符串
     * @param merData
     *            签名数据
     * @param signMsg
     *            签名消息
     * @return 返回验证结果 true 成功 false 失败
     * @throws Exception
     */
    public static Boolean verify(String publicKey, String merData, String signMsg) throws NCountException {
        boolean bVerify;
        java.security.Signature signet;
        try {
            signet = Signature.getInstance(NCountKey.SIGN_ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new NCountException("算法类型不能为空!", e);
        }

        PublicKey pubKey = getPublicKey(publicKey);

        try {
            signet.initVerify(pubKey);
        } catch (InvalidKeyException e) {
            throw new NCountException("公钥无效!", e);
        }
        try {
            signet.update(merData.getBytes(StandardCharsets.UTF_8));
        } catch (SignatureException e) {
            throw new NCountException("验签时符号异常!", e);
        }

        try {
            bVerify = signet.verify(HexStringByte.hex2byte(signMsg));
        } catch (SignatureException e) {
            throw new NCountException("验签异常!", e);
        }
        return bVerify;
    }

}
