package com.jeequan.jeepay.thirdparty.channel.yspay.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Enumeration;
import java.util.Map;


@Slf4j
public class SignRsaUtil {


    //使用RSA的加密算法对以上字符串进行签名并进行Base64编码
    public static String rsaSign(PrivateKey privateKey, String content, String charset) throws Exception {
        Signature signet = Signature.getInstance("SHA1WithRSA");
        signet.initSign(privateKey);
        signet.update(content.getBytes(charset));
        byte[] signed = signet.sign();
        return new String(Base64.encodeBase64(signed), charset);
    }

    /** 获取证书私钥 **/
    public static PrivateKey getSignCertPrivateKey(String pfxkeyfile, String keypwd) {
        FileInputStream fis = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            fis = new FileInputStream(pfxkeyfile);
            char[] nPassword = null == keypwd || "".equals(keypwd.trim()) ? null: keypwd.toCharArray();
            if (null != keyStore) {
                keyStore.load(fis, nPassword);
            }
            Enumeration<String> aliasenum = keyStore.aliases();
            String keyAlias = null;
            if (aliasenum.hasMoreElements()) {
                keyAlias = aliasenum.nextElement();
            }
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, keypwd.toCharArray());
            return privateKey;
        } catch (Exception e) {
            log.error("获取证书私钥失败！", e);
            return null;
        }finally {
            if(null!=fis) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 异步通知参数验签
     */
    public static boolean asynVerifyYsRsa(FileInputStream fileInputStream, Map<String, String> reqMap) throws Exception {
        boolean flag = false;
        //请用银盛的公钥证书
        PublicKey ysPayPublicKey = getPublicKeyFromCert(fileInputStream);

        String sign = reqMap.get("sign").trim();
        reqMap.remove("sign");
        System.out.println("签名原文:"+reqMap);
        String content = YspayKit.getSignContent(reqMap);
        System.out.println("验签数据"+content+","+sign);
        Signature signetcheck = Signature.getInstance("SHA1WithRSA");
        signetcheck.initVerify(ysPayPublicKey);
        signetcheck.update(content.getBytes(StandardCharsets.UTF_8));
        if (signetcheck.verify(Base64.decodeBase64(sign.getBytes(StandardCharsets.UTF_8)))) {
            flag = true;
        }

        return flag;
    }

    /**
     * 读取公钥，x509格式
     *
     * @param ins
     * @return
     * @throws Exception
     * @see
     */
    public static PublicKey getPublicKeyFromCert(InputStream ins) throws Exception {
        PublicKey pubKey = null;
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            Certificate cac = cf.generateCertificate(ins);
            pubKey = cac.getPublicKey();
        } catch (Exception e) {
            if (ins != null){
                ins.close();
            }
            throw e;
        } finally {
            if (ins != null) {
                ins.close();
            }
        }

        return pubKey;
    }

}
