package com.judong.chuanyiserver.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public class RSAUtil {
	
	public static void main(String[] args) {
		String a = "fsfdfdg汉字sfsf";
		String b = encryptByPublic(a, PUBLIC_KEY);
		System.out.println(b);
		try {
			String c = decrypt(b, "utf-8");
			String d = decrypt("OE9zOA6Qlvwsq0fEY3/vmK7xWq6shHLVXdRLO3Dh/0W1WHDpDcT1u4AmtennAvGzP4plhHvlrjU6E66zaMFEeGKbr8ATGAxrExl0mBqgJB/IvSyzRpv35BrghgWMm3ng+IxQlCdA/0N2IxraEweUXkgyz4745zz4xExUbE0d/N4=", "utf-8");
			System.out.println(c);
			System.out.println(d);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static final int MAX_DECRYPT = 256;
	private static final int MAX_DECRYPT_BLOCK = 245;

	/**
	 * @Title: decrypt
	 * @Description: 使用私钥解密
	 * @author: YJQ
	 * @date: 2021年4月13日 下午9:27:31
	 * @returnType String
	 * @param content
	 * @param private_key
	 * @param input_charset
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(String content, String private_key, String input_charset) throws Exception {
		PrivateKey prikey = getPrivateKey(private_key);
		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, prikey);
		InputStream ins = new ByteArrayInputStream(Base64Util.decode(content));
		ByteArrayOutputStream writer = new ByteArrayOutputStream();
		byte[] buf = new byte[MAX_DECRYPT];
		int bufl;
		while ((bufl = ins.read(buf)) != -1) {
			byte[] block = null;
			if (buf.length == bufl) {
				block = buf;
			} else {
				block = new byte[bufl];
				for (int i = 0; i < bufl; i++) {
					block[i] = buf[i];
				}
			}
			writer.write(cipher.doFinal(block));
		}
		return new String(writer.toByteArray(), input_charset);
	}

	/**
	 * @Title: decrypt
	 * @Description: 使用私钥解密
	 * @author: YJQ
	 * @date: 2021年4月13日 下午9:27:41
	 * @returnType String
	 * @param content
	 * @param input_charset
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(String content, String input_charset) throws Exception {
		PrivateKey prikey = getPrivateKey(PRIVATE_KEY);
		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, prikey);
		InputStream ins = new ByteArrayInputStream(Base64Util.decode(content));
		ByteArrayOutputStream writer = new ByteArrayOutputStream();
		byte[] buf = new byte[MAX_DECRYPT];
		int bufl;
		while ((bufl = ins.read(buf)) != -1) {
			byte[] block = null;
			if (buf.length == bufl) {
				block = buf;
			} else {
				block = new byte[bufl];
				for (int i = 0; i < bufl; i++) {
					block[i] = buf[i];
				}
			}
			writer.write(cipher.doFinal(block));
		}
		return new String(writer.toByteArray(), input_charset);
	}

	/**
	 * @Title: getPrivateKey
	 * @Description: 获得私钥
	 * @author: YJQ
	 * @date: 2021年4月13日 下午9:27:53
	 * @returnType PrivateKey
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKey(String key) throws Exception {
		byte[] keyBytes;
		keyBytes = Base64Util.decode(key);
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		return privateKey;
	}

	/**
	 * @Title: getPublicKeyFromX509
	 * @Description: 得到公钥
	 * @author: YJQ
	 * @date: 2021年4月13日 下午9:28:00
	 * @returnType PublicKey
	 * @param bysKey
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws Exception
	 */
	private static PublicKey getPublicKeyFromX509(String bysKey) throws NoSuchAlgorithmException, Exception {
		byte[] decodedKey = Base64Util.decode(bysKey);
		X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodedKey);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePublic(x509);
	}

	/**
	 * @Title: encryptByPublic
	 * @Description: 使用公钥加密
	 * @author: YJQ
	 * @date: 2021年4月13日 下午9:28:07
	 * @returnType String
	 * @param content
	 * @param pub_key
	 * @return
	 */
	public static String encryptByPublic(String content, String pub_key) {
		try {
			PublicKey pubkey = getPublicKeyFromX509(pub_key);
			Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
			cipher.init(Cipher.ENCRYPT_MODE, pubkey);
			// 分段加密
			byte[] data = content.getBytes("UTF-8");
			int inputLength = data.length;
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			int offset = 0;
			byte[] cache;
			int i = 0;
			while (inputLength - offset > 0) {
				if (inputLength - offset > MAX_DECRYPT_BLOCK) {
					cache = cipher.doFinal(data, offset, MAX_DECRYPT_BLOCK);
				} else {
					cache = cipher.doFinal(data, offset, inputLength - offset);
				}
				out.write(cache);
				i++;
				offset = i * MAX_DECRYPT_BLOCK;
			}
			byte[] decryptedData = out.toByteArray();
			out.close();
			return new String(Base64Util.encode(decryptedData));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/* 私钥 */
	public static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJszNAoIzCXk81ZJ\r\n"
			+ "jmhfwWbW0HxnHSLKnekIyGgkfdgJpXtPe+ca9DSC5J4h2C6liZix0/kVnUcBa3F6\r\n"
			+ "/H2C6222BObb5PLBqJhfrXry23tOA4PZDRhmtyzwDQHlvFLhJkaaKEp4/Wf5F2b6\r\n"
			+ "1VJAvGGw35+YD+hHvsTvHQHxfVCbAgMBAAECgYAdNV+/27QAFbyuKp3AivTtE9Sc\r\n"
			+ "9RMIrzVU3DBLWULN29LnCCh7cBkxoMjB8gCrlr/0mtMX97dn256K9uh5/p+r9R+j\r\n"
			+ "30TUmLDa0fi0WNXHZ+FitYGdBhtcdaYiDsiDKIe87ItCKH/cfazgUOV9AjqaDlxp\r\n"
			+ "x6qhsPDosA/O7JidcQJBAMvvI6YUJ2+PKPUKgWZ55JZMpSUAJXmP5OfvFb+hBmst\r\n"
			+ "ErzVMMhoBUF7g/6NXWDz8fmDiy5s8/c4X742cIxsVScCQQDC0t4B9BTje7PZ+s5Y\r\n"
			+ "PY1NOLR3xP+3uG89J+7JW87zXEKDHejrR7KNkjb3rWl8NJvdP+6iv1yERu6n/Hcm\r\n"
			+ "udltAkA0ZHKvJzxeb9Qg6BsIfcZZSsWetOPr0CkJ4SWgPrlMbZ8Dvm2y/u5ivV3S\r\n"
			+ "1vSnhOSkqsPmIH2pBOWsE4ZkvSw/AkEAjuPf5qjhhTMeZxrXqsqCT4fufQWk1FfW\r\n"
			+ "ZpFaRp8qez1InygZxC7S25jI7gFnI6zmQHD6kq0tqurncZfuwB2BRQJAc5XbwsEj\r\n"
			+ "lhvSnGHx2fe9c/BzaM7J575aJLtVPq3NrO3APMTwSGmK1kTiE+13041QHRVN25Ni\r\n"
			+ "uaqJA3hsfOTwQA==";

	/* 公钥 */
	public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbMzQKCMwl5PNWSY5oX8Fm1tB8\r\n"
			+ "Zx0iyp3pCMhoJH3YCaV7T3vnGvQ0guSeIdgupYmYsdP5FZ1HAWtxevx9gutttgTm\r\n"
			+ "2+TywaiYX6168tt7TgOD2Q0YZrcs8A0B5bxS4SZGmihKeP1n+Rdm+tVSQLxhsN+f\r\n"
			+ "mA/oR77E7x0B8X1QmwIDAQAB";

}