package cc.smtweb.framework.core.util;


import org.apache.commons.codec.binary.Base64;

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;

/**
 * Created by Akmm at 2020/4/23 15:23
 */
public class RSAUtil {
    private static final KeyPair keyPair = initKey();

    private static KeyPair initKey() {
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(1024, new SecureRandom());
            // 生成一个密钥对，保存在keyPair中
            return keyPairGen.generateKeyPair();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String generateBase64PublicKey() {
        PublicKey publicKey = keyPair.getPublic();
        return new String(Base64.encodeBase64(publicKey.getEncoded()));
    }

    public static String generateBase64PrvKey() {
        PrivateKey privkey = keyPair.getPrivate();
        return new String(Base64.encodeBase64(privkey.getEncoded()));
    }

    public static String decryptBase64(String string) throws Exception {
        byte[] byteArray = Base64.decodeBase64(string.getBytes());
        Cipher cipher = Cipher.getInstance("RSA");
        PrivateKey privateKey = keyPair.getPrivate();
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] plainText = cipher.doFinal(byteArray);
        return new String(plainText);
    }

    /**
     * 利用我们提供的密钥加密
     *
     * @param str
     * @return
     * @throws Exception
     */
    public static String encryptBase64(String str) throws Exception {
        PublicKey pubKey = keyPair.getPublic();
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
    }

    /**
     * 指定RSA公钥加密
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String encryptBase64(String str, String publicKey) throws Exception {
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);

        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
    }

    /**
     * 指定RSA私钥解密
     *
     * @param str        加密字符串
     * @param privateKey 私钥
     * @return 铭文
     * @throws Exception 解密过程中的异常信息
     */
    public static String decryptBase64(String str, String privateKey) throws Exception {
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        String outStr = new String(cipher.doFinal(inputByte));
        return outStr;
    }

    public static void main(String[] args) throws Exception {
        String ss = "我的123";
        /*String ss = "UR/ykQMQiLePbUFIlRYkUIaDcxDTYVOK9uTwqkbwlo6OcFzs0sQL+qzRMYBYCOC+ufLSSbQgwgbb+gxWf5GP5QyH5ygp4XHOa6IWbILHDB1nqze4S+NKhR72UOMqY5J4/C2ZZyiTQKTY5KJzn1gtjEbrzBHEFQEBTIJbg5k2zu4=";
        String pk = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIBwwtBhDftNsYLUMQme/Av+RQKg32wmhkd7m2hm/CZu+FnNsWCIGt7pmCVfIdnJCgm15HjmW/alfLO5XDDacRVmL" +
                "I5pvmv6jCki+BoquUMQFV3pJcgSMg/MocdACPkXSvB/m7IhDu2P3eXIx55aieLiPDciujiOD9Do5AmicM07AgMBAAECgYAha7X1fNujgYLoFQixhTH2ePJCDdQ1Ew0ruokksG96HLP4wi" +
                "IeiSvcxxG0370yKzK2diL+JorVchgxt9C6UYzM8o+b4NflFCuKqfUCk63fTrBeXI0OaUFJATxxXfqzNgDaWgiqItRE/h1rBtQG5FQ0V1zFE+pLPSK+bnD6uWpFEQJBAM1x8pFOdnP8+iX" +
                "brt+dHeFttOLFt8OS/TVD2ZD+NblxPYYRha89a9mLb0TkErEnQEegoA1Dq+4c+4Ayx3+nnykCQQCgC+Rr+pilMIUuJSnBbY4+Mn2cgRNhQX+w2cDpXNxtFi1eld2MjHgVbp+VmivGSDBe" +
                "c/Oq7qSnEITWLxYsvSnDAkB1AZmh8ir6YjDhkN1m06fp9L5ZjTvcsgFt7aeisXVNmVXt3lrh9DxRWN1VQgP3SyCL6spc45au9WizmbgPVxsJAkAqUPqkUi3p/1o3STwxGHZzm4X6y2YEY" +
                "P0SFYEcMqFVdneoepeJgdp+UDGBrLHGS2/+iUnz+AUw5v04ZFrImXthAkAfoPdHP00CFsvIK4fK/iBboDPmY014/DR+W8jfJHHu5Lv0XuYvdNsrvM9GL+UNgjNTCF0OT3UWFfq5Hrta89vZ";
        System.out.println(decryptBase64(ss, pk));*/
        String pubkey = generateBase64PublicKey();
        System.out.println("pubkey::::::::::::::" + pubkey);
        PrivateKey pKey = keyPair.getPrivate();
        String prvkey = new String(Base64.encodeBase64(pKey.getEncoded()));
        System.out.println("prvkey::::::" + prvkey);

        System.out.println("encrypt1::::::" + encryptBase64(ss));
        String en = encryptBase64(ss, pubkey);
        System.out.println("encrypt2::::::" + en);

        System.out.println("decrypt1::::::" + decryptBase64(en));


        System.out.println("decrypt2::::::" + decryptBase64(encryptBase64(ss), prvkey));
    }
}
