package com.schoolinout.common.utils.sign;

import org.apache.commons.codec.binary.Base64;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

@Component
public class RSAUtil {
    private static final RSAKeyPair rsaKeyPair = new RSAKeyPair();
    // Rsa 私钥 也可固定秘钥对 若依原写法(不安全)
    public static String privateKeys = "";
    private static String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt+nZS3z0N7Yv6++/BpqK\n" +
            "ee0x+G3G0p3YcQPw0twfGAfH1FPsj69QF9nm/UjjEaqzgzSM8ScaSo6eziXoeqJL\n" +
            "VhknA9LknIEuMc+zEftjEpGv+7TPQeaKnw/toh9tYR5ItT1MIimqj/rGc9cPZeBy\n" +
            "lKnZ+yiGKoMVOTQmiVaORHYjV6Syg8sIkfGyWLb5BSvfOv+TOdjlP2+H0yj1r9oT\n" +
            "k67ZV9plpfTCCEa+xb1tgcSuWBwCpRR5AjlMU7uH18a1cyXV++7NRhmZd/Jd9KB+\n" +
            "WNbS1MtpIyqSlvyPFzpQvPTPxCV2TFb+uqDTX4WIBJNFDRUJe8JjTEjlf+AF5yCD\n" +
            "7QIDAQAB";
    private static String privateKeyStr = "MIIEowIBAAKCAQEAt+nZS3z0N7Yv6++/BpqKee0x+G3G0p3YcQPw0twfGAfH1FPs\n" +
            "j69QF9nm/UjjEaqzgzSM8ScaSo6eziXoeqJLVhknA9LknIEuMc+zEftjEpGv+7TP\n" +
            "QeaKnw/toh9tYR5ItT1MIimqj/rGc9cPZeBylKnZ+yiGKoMVOTQmiVaORHYjV6Sy\n" +
            "g8sIkfGyWLb5BSvfOv+TOdjlP2+H0yj1r9oTk67ZV9plpfTCCEa+xb1tgcSuWBwC\n" +
            "pRR5AjlMU7uH18a1cyXV++7NRhmZd/Jd9KB+WNbS1MtpIyqSlvyPFzpQvPTPxCV2\n" +
            "TFb+uqDTX4WIBJNFDRUJe8JjTEjlf+AF5yCD7QIDAQABAoIBAAI+uIhTXifP8YXP\n" +
            "x2UtPcN/Qbzmmia4Boxan/Xy+e4xKh9NZvXaDgA8iLVOznbIvqg7W/0VnRyL4SRj\n" +
            "EhNtJ75FUFSbnm7KpOW2w1jU2MDBRoSsEFudlNOcPipcd9lXpUuRE/zWxV48kW+Y\n" +
            "kHeN5dgqup52QC0ErJ2mJVJH3DS5tyRg5icvhGW92FcJWszrf8oKN94RBe7t9vn8\n" +
            "kx/sVzzCfQNIBAKtZzcpbBmO0ZaWy6vgpQ6UUo0AEbW4S3OS8wXotELMw+dfWOne\n" +
            "6bZX2vX5ANJCpJOaybYFLmX1llAyCFte8gQ4weVlUGpZ05vb5R7dfMqRQxy7P5+/\n" +
            "odXdO4ECgYEA6sEkFCAwAMyaTjTl8OhKc0K8CNZKnaJ19zqFUHyQGRwkFWBuWw4m\n" +
            "aErZgsZxOyWlJE5K00VAi0gt2IY7ZHR3I0bL/V5j6BBcD6PdqZpakaCyhikTdYFO\n" +
            "5Y2folt1I6ZVl5hkO8Q9aP5ncNsf8ip7ALuNNmg3ah26xS9Hns80DVcCgYEAyI7P\n" +
            "Kyl4mpFsfC2DpNMvRlt2IVZ4hRF8y33nITN1xFrUcDNAv33A8eEQB9f2tb/XIshv\n" +
            "mySBpZ+bOaFWzauAqPBHO1WIwAu9cmYOcBxU3g3pzi+64kXmxmDB6Ssih2XfCuv6\n" +
            "YnppjBYTr2yjraHu/lCyLKilUN0o5HnLGIjcqlsCgYBNxOQ94pfke+OWiwGt+FZJ\n" +
            "rs76InufkyV/XJyzmEBogSEXD9YfRiXFIR7Dqxfx3zvBNkqliOij+6psc7OTSN37\n" +
            "CsYjTrTMOTc2WzPgrujYG6NovIzcvZS0iWFb+O5qe/0Y9nwmLJGnibgc9Aq2QAp1\n" +
            "qKxUXNwWxHiOQGZ6nuwAiwKBgGNN4uJaPG88Rl0OJDq+no/VxZ4oNLCewg34HzNf\n" +
            "SZaZ6spLdmnamGirqcZYdr3zaVC9shU9dDxP1QoqCtL3clMz9fE5HucIaRt10PxN\n" +
            "6u+wL+55z60uM2BSlHEhfI1SMag0w9tzBUPpwoF/52OX5MBjsHVQY9qwRwkqDRfu\n" +
            "3GQ1AoGBAM5j3geg4MwU/7Uxd/zG4Jv800RZwLxoAj8yj++sDQaTwooZxuwBL91t\n" +
            "6hKmDlpOMMGsK/BS/2IO7CRxM9RB8dvNhU5/YrfszsKfJ/Fcs7XNcAQn6uqMOJAx\n" +
            "lZd4FKpkpCcJQDkeh9unIQzxwDabXG6BMaxyWLLhSdRJEmSBjmPJ";

    /**
     * 私钥解密
     *
     * @param text 待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String text) throws Exception {
        return decryptByPrivateKey(rsaKeyPair.getPrivateKey(), text);
    }

    /**
     * 公钥解密
     *
     * @param publicKeyString 公钥
     * @param text            待解密的信息
     * @return 解密后的文本
     */
    public static String decryptByPublicKey(String publicKeyString, String text) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 私钥加密
     *
     * @param privateKeyString 私钥
     * @param text             待加密的信息
     * @return 加密后的文本
     */
    public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 私钥解密
     *
     * @param privateKeyString 私钥
     * @param text             待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 公钥加密
     *
     * @param publicKeyString 公钥
     * @param text            待加密的文本
     * @return 加密后的文本
     */
    public static String encryptByPublicKey(String publicKeyString, String text) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    public static String getPublicKey() {
        return publicKeyStr;
    }

    public static String getPrivateKey() {
        return privateKeyStr;
    }

    public static RSAKeyPair rsaKeyPair() {
        return rsaKeyPair;
    }

    /**
     * 构建RSA密钥对
     *
     * @return 生成后的公私钥信息
     */
    @Bean
    public void generateKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        rsaKeyPair.setPrivateKey(privateKeyString);
        rsaKeyPair.setPublicKey(publicKeyString);
        publicKeyStr = publicKeyString;
        privateKeyStr = privateKeyString;
    }

    /**
     * RSA密钥对对象
     */
    public static class RSAKeyPair {
        private String publicKey;
        private String privateKey;

        public RSAKeyPair() {

        }

        public RSAKeyPair(String publicKey, String privateKey) {
            this.publicKey = publicKey;
            this.privateKey = privateKey;
        }

        public String getPublicKey() {
            return publicKey;
        }

        public void setPublicKey(String publicKey) {
            this.publicKey = publicKey;
        }

        public String getPrivateKey() {
            return privateKey;
        }

        public void setPrivateKey(String privateKey) {
            this.privateKey = privateKey;
        }
    }
}
