RSA工具包

RSAUtils

  • 代码

代码


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class RSAUtils {

	public static final String RSA = "RSA";// 非对称加密密钥算法
	public static final String ECB_PADDING = "RSA/ECB/PKCS1Padding";// 加密填充方式

	/**
	 * RSA算法规定:待加密的字节数不能超过密钥的长度值除以8再减去11。 而加密后得到密文的字节数,正好是密钥的长度值除以 8。
	 * 密钥位数
	 */
	private static final int KEY_SIZE = 1024;
	private static final int RESERVE_BYTES = 11;
	/**
	 * RSA最大解密密文大小
	 */
	private static final int DECRYPT_BLOCK = KEY_SIZE / 8;
	/**
	 * RSA最大加密明文大小117
	 */
	private static final int ENCRYPT_BLOCK = DECRYPT_BLOCK - RESERVE_BYTES;

	/**
	 * 私钥
	 */
	private static final String privateKeyString = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIsQBZlv8j8RfDoD5NtKYgfQSEmFE49IF1etuE0KuYugtv0yNs9oj3CnkScw93qIF9A5yoqC755IYSGwKYrPnHgas473opeb//jysizI0F2gR2bQ23/kLykXVZoRkmhvO8Gr+OdaJ4ja1F7you97onNKrN70ixeylFkOzi0gpsgTAgMBAAECgYAL38Zan7Bzqi6NVZ/JCcTtHd/OR0qwRVuY5QCDs5K8VXDKlesQMsFswSIn0oqPL+e4o/ajdSK4xT1l/wDNFYUqq13rPfSCAK45xjSEBLpNTP/o/l8xa9lha69KFYN6rCTCsSQaES++/u6a/BchsdTVkP+M3JxfBYBVKclOlSaj4QJBAOaNws0n+GXhvSfROjyKHZJvRLznd5v62WiMpAhXhmmcVCUmehpRIHlT7legUzLmAW77MxGx+3J4HnP7WdC1zP0CQQCaaTNgeMtB0aHhSA0GOJ3Gm0o7Gqb58LsMQmJUACKiSUs4jvDCOZQs6TRHeI5VPyApaawPzoONiy4/Zkv4yH5PAkBfud53JjBpxOev/5xphIMwyMhGkujDt8zLLxHwcL7bXNBHOImcIbEVDzc35NaGnJ9dwCj9IOQhLCSgzW0GTmXVAkBmuIFzNiiRerHkOphfgR6E1x3Ev/BA6cKlXywmkYh4yaV+1KiZrNBEKEedHDgjwcDVi/To9wtRCDwV9SmpMUfFAkEAzWjcOaSmMB+WaMCuYEggsbPW9KUXw8kP/Vi061S3r6E6AcLG2vyWvms8LsMhH9acXm5QoeUnwcN0LI63tYqoEw==";
	/**
	 * 公钥
	 */
	private static final String publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCLEAWZb/I/EXw6A+TbSmIH0EhJhROPSBdXrbhNCrmLoLb9MjbPaI9wp5EnMPd6iBfQOcqKgu+eSGEhsCmKz5x4GrOO96KXm//48rIsyNBdoEdm0Nt/5C8pF1WaEZJobzvBq/jnWieI2tRe8qLve6JzSqze9IsXspRZDs4tIKbIEwIDAQAB";

	/**
	 * 生成密钥
	 */
	public static Map genKeyPair() {

		Map keyMap = new HashMap<>(); // 用于封装随机产生的公钥与私钥

		try {
			// 生成一个密钥对,保存在keyPair中
			KeyPair keyPair = generateKeyPair(512);
			assert keyPair != null;
			RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
			RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥

			// 得到公钥字符串
			String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
			// 得到私钥字符串
			String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));

			// 将公钥和私钥保存到Map
			keyMap.put(0, publicKeyString); // 0表示公钥
			keyMap.put(1, privateKeyString); // 1表示私钥
		} catch (Exception e) {
			log.info("生成公钥私钥异常:" + e.getMessage());
			return null;
		}
		System.out.println(JSON.toJSONString(keyMap, JSONWriter.Feature.PrettyFormat));
		return keyMap;
	}

	public static void main(String[] args) throws Exception {
		String s = "13241234";
		String s1 = encrypt(s);
		System.out.println("加密后:" + s1);
		System.out.println("解密后:" + decrypt(s1));
	}

	/**
	 * 随机生成RSA密钥对
	 *
	 * @param keySize 密钥长度,范围:512-2048,一般2048
	 */
	public static KeyPair generateKeyPair(int keySize) {
		try {
			KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
			kpg.initialize(keySize);
			return kpg.genKeyPair();
		} catch (Exception e) {
			log.error("generateKeyPair exception.", e);
			return null;
		}
	}

	/**
	 * 读取私钥
	 * @throws Exception 返回私钥的key对象
	 */
	private static String getPrivateKey() throws Exception {

		//创建key的工厂
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		//创建私钥key的规则
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
		//返回私钥对象

		return new String(Base64.encodeBase64(keyFactory.generatePrivate(keySpec).getEncoded()));
	}

	/**
	 * 读取公钥
	 *
	 * @return 公钥字符传
	 * @throws Exception 返回公钥的key对象
	 */
	private static String getPublicKey() throws Exception {

		//创建key的工厂
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		//创建公钥key的规则
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
		//返回公钥对象
		PublicKey publicKey = keyFactory.generatePublic(keySpec);
		return new String(Base64.encodeBase64(publicKey.getEncoded()));

	}

	public static PublicKey getPublicKey(byte[] key) throws Exception {
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(RSA);
		return keyFactory.generatePublic(keySpec);
	}

	public static PrivateKey getPrivateKey(byte[] key) throws Exception {
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(RSA);
		return keyFactory.generatePrivate(keySpec);
	}

	/**
	 * 公钥加密
	 *
	 * @param plain 加密的内容
	 */
	public static String encrypt(String plain) throws Exception {
		byte[] data = plain.getBytes(StandardCharsets.UTF_8);
		//得到公钥
		String publicKey = getPublicKey();
		byte[] key = Base64.decodeBase64(publicKey);

		byte[] result = encryptWithPublicKeyBlock(data, key);
		return Base64.encodeBase64String(result);
	}

	/**
	 * 私钥解密
	 *
	 * @param plain 解密的内容
	 */
	public static String decrypt(String plain) {
		try {
			byte[] data = Base64.decodeBase64(plain.getBytes(StandardCharsets.UTF_8));
			String privateKey = getPrivateKey();
			byte[] key = Base64.decodeBase64(privateKey);

			byte[] bytes = decryptWithPrivateKeyBlock(data, key);
			return new String(bytes);
		} catch (Exception e) {
			log.error("decryptWithPrivateKeyBlock exception.", e);
		}
		return "";
	}

	public static byte[] encryptWithPublicKeyBlock(byte[] data, byte[] key) throws Exception {
		Cipher cipher = Cipher.getInstance(ECB_PADDING);
		cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(key));
		int inputLength = data.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offset = 0;
		byte[] cache;
		int i = 0;
		while (inputLength - offset > 0) {
			if (inputLength - offset > ENCRYPT_BLOCK) {
				cache = cipher.doFinal(data, offset, ENCRYPT_BLOCK);
			} else {
				//防止传入的data 长度过长 进行分片处理
				cache = cipher.doFinal(data, offset, inputLength - offset);
			}
			out.write(cache, 0, cache.length);
			i++;
			offset = i * ENCRYPT_BLOCK;
		}
		byte[] bos = out.toByteArray();
		out.close();
		return bos;
	}

	public static byte[] decryptWithPrivateKeyBlock(byte[] data, byte[] key) throws Exception {
		int blockCount = (data.length / DECRYPT_BLOCK);
		if ((data.length % DECRYPT_BLOCK) != 0) {
			blockCount += 1;
		}
		ByteArrayOutputStream bos = new ByteArrayOutputStream(blockCount * DECRYPT_BLOCK);
		Cipher cipher = Cipher.getInstance(ECB_PADDING);
		cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(key));
		for (int offset = 0; offset < data.length; offset += DECRYPT_BLOCK) {
			int inputLen = (data.length - offset);

			if (inputLen > DECRYPT_BLOCK) {
				inputLen = DECRYPT_BLOCK;
			}

			byte[] decryptedBlock = cipher.doFinal(data, offset, inputLen);
			bos.write(decryptedBlock);
		}

		bos.close();
		return bos.toByteArray();
	}
}

你可能感兴趣的:(工具,java)