package com.yn.bftl.thirdparty.common.util;

import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

/**
 * 加密工具类
 *
 * @author huabiao
 * @create 2022/9/7  10:36
 **/
public class CryptoUtils {

    public static PrivateKey initPrivateKeyFromFile(File file, String pwd){
        try{
            KeyStore ks = KeyStore.getInstance("PKCS12");
            FileInputStream fin = new FileInputStream(file);
            ks.load(fin, pwd.toCharArray());
            return  (PrivateKey)ks.getKey(ks.aliases().nextElement(),pwd.toCharArray());
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    public static PrivateKey initPrivateKeyFromByteArray(byte[] byteArray, String pwd){
        try{
            ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
            KeyStore ks = KeyStore.getInstance("PKCS12");
            ks.load(bais, pwd.toCharArray());
            return  (PrivateKey)ks.getKey(ks.aliases().nextElement(),pwd.toCharArray());
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }


    /**
     * 生成签名
     * @param algorithm 签名算法
     * @param content 原文
     * @param priKey 私钥
     * @param charset 字符编码
     * @return 签名
     */
    public static String sign(String algorithm, String content, PrivateKey priKey, String charset){
        try {
            Signature signature = Signature.getInstance(algorithm);
            signature.initSign(priKey);
            signature.update(content.getBytes(charset));
            return Hex.toHexString(signature.sign());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 验证签名
     * @param algorithm 签名算法
     * @param content 原文
     * @param sign 签名
     * @param pubKey 公钥
     * @param charset 字符编码
     * @return 是否验签通过
     */
    public static boolean verifySign(String algorithm, String content, String sign, PublicKey pubKey, String charset){
        try {
            Signature signature = Signature.getInstance(algorithm);
            signature.initVerify(pubKey);
            signature.update(content.getBytes(charset));
            return signature.verify(Hex.decode(sign));
        } catch (Exception e) {
            //验签失败
            throw new RuntimeException(e);
        }
    }

    public static PublicKey initPublicKeyFromHexString(String hexString){
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Hex.decode(hexString));
        try {
            return KeyFactory.getInstance("RSA").generatePublic(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static PublicKey initPublicKeyFromBase64String(String base64String){
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(base64String));
        try {
            return KeyFactory.getInstance("PKCS12").generatePublic(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static PrivateKey initPrivateKeyFromHexString(String hexString){
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Hex.decode(hexString));
        try {
            return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static PrivateKey initPrivateKeyFromBase64String(String base64String){
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(base64String));
        try {
            return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static PublicKey loadPublicKeyFromBase64(String base64EncodedKey) {
        byte[] decodedBytes = java.util.Base64.getDecoder().decode(base64EncodedKey);
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 或其他密钥类型
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedBytes);
            return keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new RuntimeException("Error loading public key", e);
        }
    }

}
