package com.yihu.jw.util.common;

import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.Assert;


public class RSAUtils {

//    private static final KeyPair keyPair = initKey();

    /**
     * 算法名称
     */
    private static final String ALGORITHOM = "RSA";
    /**
     * 默认的安全服务提供者
     */
    private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();

    public static KeyPair initKey(){
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            SecureRandom random = new SecureRandom();
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
            generator.initialize(1024, random);
            return generator.generateKeyPair();
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成public key
     * @return
     */
    public static String generateBase64PublicKey(KeyPair keyPair){
        RSAPublicKey key = (RSAPublicKey)keyPair.getPublic();
        return new String(Base64.encodeBase64(key.getEncoded()));
    }

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

    /**
     * 解密
     * @param string
     * @return
     */
    public static String decryptBase64(String string,KeyPair keyPair) {
        return new String(decrypt(Base64.decodeBase64(string),keyPair));
    }

    public static byte[] decrypt(byte[] string,KeyPair keyPair) {
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
            RSAPrivateKey pbk = (RSAPrivateKey)keyPair.getPrivate();
            cipher.init(Cipher.DECRYPT_MODE, pbk);
            byte[] plainText = cipher.doFinal(string);
            return plainText;
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /** 安全服务提供者 */
    private static final Provider PROVIDER = new BouncyCastleProvider();

    /**
     * 加密
     * 
     * @param publicKey
     *            公钥
     * @param data
     *            数据
     * @return 加密后的数据
     */
    public static byte[] encrypt(PublicKey publicKey, byte[] data) {
        Assert.notNull(publicKey);
        Assert.notNull(data);
        try {
            Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", PROVIDER);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 加密
     * 
     * @param publicKey
     *            公钥
     * @param text
     *            字符串
     * 
     * @return Base64编码字符串
     */
    public static String encrypt(PublicKey publicKey, String text) {
        Assert.notNull(publicKey);
        Assert.notNull(text);
        byte[] data = encrypt(publicKey, text.getBytes());
        return data != null ? Base64.encodeBase64String(data) : null;
    }

    /**
     * 使用指定的私钥解密数据。
     *
     * @param privateKey 给定的私钥。
     * @param data       要解密的数据。
     * @return 原数据。
     */
    public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {
        Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
        ci.init(Cipher.DECRYPT_MODE, privateKey);
        return ci.doFinal(data);
    }

    public static void main(String[] args) {

        KeyPair keyPair =  initKey();
        // 生成public key
        String aa = encrypt(keyPair.getPublic(), "ee");
        System.out.println(aa);

        // 解密
        System.out.println(decryptBase64(aa,keyPair));
    }


}
