package com.tofly.auth.util;

import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA 加解密
 */
public class RSAUtils {

    /**
     * RSA 公钥和私钥
     * 通过RSA密钥处理器获得，而非自定义字符串  照抄即可
     */
    public final static String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzkMQ3VQcbmpKtqKsuI4EByAz2" +
            "Il3v8eKb9JMv2UuPqyMpzG8HRD5I/Wu6SqlCeDjMy04dzzec2Hx2Z3ChcYvrA3KZ" +
            "Wqt8z7e6P6XimA5itNAfXGSEam8ST/ZVVYagAWH8eCbyX07itwTNVug9qVdH1Dy/" +
            "SBsGNYKrx9Vf2x9wrwIDAQAB";
    public final static String priKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALOQxDdVBxuakq2o" +
            "qy4jgQHIDPYiXe/x4pv0ky/ZS4+rIynMbwdEPkj9a7pKqUJ4OMzLTh3PN5zYfHZn" +
            "cKFxi+sDcplaq3zPt7o/peKYDmK00B9cZIRqbxJP9lVVhqABYfx4JvJfTuK3BM1W" +
            "6D2pV0fUPL9IGwY1gqvH1V/bH3CvAgMBAAECgYAIo+slJHTCmcX8EDUoc7Hl9YvW" +
            "HiI6BQAb9AFPGJwfriLzhHBFP73lgjg4TxZk6ecFx7SbD5kD9ZDLm7+aLR4H3IVr" +
            "mmj3llMuDv/TyhWwan6nxzo7GgFvq1Lxi+vJVLStbITfSwHA0dIPyOo5qzj7wPgQ" +
            "P+HL/R7Cp/Ga2HNuPQJBAP3YjibIii7uOhoTu20OUF+mXvgH0IhkBq89n6kTqh23" +
            "yC3qKLqjWauWYg0E9ATEHVWzY+JKxiG27X8waRbosfUCQQC1Ftjs+GuFfTN/piPt" +
            "jI2MZmlBVRXtxUHgErUykkaAV0TLSf6fbiMTuKY6GPsv3eTOMEkD021Cso4grs3E" +
            "Jp2TAkA27nPkhKUSfs7n8bkvYleWO0R13AsOWMbxiR5R0kWP5MNW3EMwEEVJUmOp" +
            "eZbsqRvH/efxgkjZ5uICEhHLuVM5AkAc00Y0clarKQLJjuipJ3ZgouyeOa0D7CJQ" +
            "SKoPIrmWNE3/Dgg52I481WegV9mkBO4m5Ai7UyxRMZruGOUoE/2BAkB2BwIwZMWL" +
            "StiV2dtlsqoYclyCzzCIncy2ljGk7Mcg05v2MiTmiH9Y7lA1eSSAyZRAxSl9BkEs" +
            "RqE98G16GCrt";



    /**
     * 公钥加密
     *
     * @param str 需要加密操作的字符串
     * @return 结果再Base64加密后的字符串
     * @throws Exception
     */
    public static String pubKeyEncryption(String str) throws Exception {
        // String 转 公钥
        PublicKey rsaPublicKey = getPublicKey(pubKey);
        //公钥加密
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(str.getBytes());
        return Base64.encodeBase64String(result);
    }


    /**
     * 用私钥 解密
     *
     * @param encryptionBase64Str RSA加密后又base64编码后的字符串
     * @return 解密结果
     * @throws Exception
     */
    public static String priKeyDecryption(String encryptionBase64Str) throws Exception {
        // base64 解码
        byte[] base64 = Base64.decodeBase64(encryptionBase64Str);
        // String 转 私钥
        PrivateKey rsaPrivateKey = getPrivateKey(priKey);
        //私钥解密
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(base64);
        return new String(result);
    }


    /**
     * String转公钥PublicKey
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes;
        keyBytes = (new BASE64Decoder()).decodeBuffer(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * String转私钥PrivateKey
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes;
        keyBytes = (new BASE64Decoder()).decodeBuffer(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

}

