RSA 非对称加密

前端调用

依赖

jsencrypt.min.zip

jsencrypt.js
使用
jsEncriptStr: function (publicKey, str) {
          const rsa = new JSEncrypt()
          
          rsa.setPublicKey(publicKey)
          return rsa.encrypt(str)
      }

RSA 工具类

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

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

public class RSAUtils {

	public static final String CHARSET = "UTF-8";
	public static final String RSA_ALGORITHM = "RSA";
	//公钥
	public static final String PUBLIC_KEY = "RSAPublicKey";

	//私钥
	public static final String PRIVATE_KEY = "RSAPrivateKey";

	public static Map<String, Object> createKeys(int keySize) {
		// 为RSA算法创建一个KeyPairGenerator对象
		KeyPairGenerator kpg;
		try {
			kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
		} catch (NoSuchAlgorithmException e) {
			throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
		}

		// 初始化KeyPairGenerator对象,密钥长度
		kpg.initialize(keySize);
		// 生成密匙对
		KeyPair keyPair = kpg.generateKeyPair();
		// 得到公钥
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		//得到私钥
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		Map<String, Object> keyPairMap = new HashMap<>();
		keyPairMap.put(PUBLIC_KEY, publicKey);
		keyPairMap.put(PRIVATE_KEY, privateKey);

		return keyPairMap;
	}
	public static void main(String args[]) throws Exception {
//		Map<String, Object> keyPairMap=RSAUtils.createKeys(1024);
		String publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWL9Y58MzKXfjE8mi7E+f74b9fnEZ6vCAsueZIPctbKTY8Anq7V+GRHU5vAqHXBsJEFk3g/OChTSExbXL35jZ8p/pqtaPkncv2TPkp4qHMBDtPO/MoItodeEBkF3azarYwIfapqdKItcrSSf7xdrEtxSmDtNrMVlu6CZQb41iB0QIDAQAB";

		String privateKey="MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJYv1jnwzMpd+MTyaLsT5/vhv1+cRnq8ICy55kg9y1spNjwCertX4ZEdTm8CodcGwkQWTeD84KFNITFtcvfmNnyn+mq1o+Sdy/ZM+SniocwEO0878ygi2h14QGQXdrNqtjAh9qmp0oi1ytJJ/vF2sS3FKYO02sxWW7oJlBvjWIHRAgMBAAECgYBArKz2Goo2Ay2jsjgDh9j4kQhWZfe71tOMLynJpkKyKRcf1HmBv6B1W0dxapLDBDgYFfrHjl41V/+ZR2ag9lQzxTNnKqP2HMHxXJsnOLUAiLHp4d/T90s/9/GxFY/gj93vtcSouZPlmpWpnh1MamWMalhiFOIEynmO9BCpTWJnmQJBAMp6ACgYdvJygW5+tbAkOc27lb337UidfldW9PV+VKfE7SaFBFkjUaSq6P4dOk1LQb7zJ90x1tAJiakKr07o+RMCQQC940k+eNzII91FQ/m0Xb0xmLgGSK3TVPTf1wwMbVRnoT3eboVY17cW+RX7XBiDhvy74LmpJLCLeF1arjQV6roLAkEAxMbEmDMOhpmaCJTEZqcONk90O+dTiBrnymIMNvnLtDDCeYkUrLySgAJJ5YzqOGxHPRh7SZFCP3TFgK+NqJbqWQJBAIU5HX4zFdNlNi0Oj/a3fbF6UEI4Y5xNkrApFE7ztbAvNFUGfY/jaJU5lO6RorFE17SI6jl9gE+Z1wV0Cx8FXBkCQQDG0XdwPbpipnmxl2cKz2fuKBOh90xHkuBCfKJKLHd1peZpet9j9XRJU0d/3HKeMuaAvxWV+mfnwHoag3/g8k6K";
//		String publicKey=getPublicKey(keyPairMap);
//		String privateKey=getPrivateKey(keyPairMap);
		System.out.println("publicKey:"+publicKey);
		System.out.println("privateKey:"+privateKey);
		String str="lingrui570@IOT";
		try {
			//加密
			String after=RSAUtils.publicEncrypt(str,RSAUtils.getPublicKey(publicKey));
			System.out.println("字符串:"+str);
			System.out.println("加密后:"+after);
			//解密
			String before=RSAUtils.privateDecrypt(after,RSAUtils.getPrivateKey(privateKey));
			System.out.println("解密后:"+before);

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		}


	}

	/**
	 * 取得私钥
	 *
	 * @param keyMap
	 * @return
	 * @throws Exception
	 */
	public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PRIVATE_KEY);
		return toBase64(key.getEncoded());
	}

	/**
	 * 取得公钥
	 *
	 * @param keyMap
	 * @return
	 * @throws Exception
	 */
	public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PUBLIC_KEY);
		return toBase64(key.getEncoded());
	}
	/**
	 * 得到公钥
	 * 
	 * @param publicKey
	 *            密钥字符串(经过base64编码)
	 * @throws Exception
	 */
	public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
		// 通过X509编码的Key指令获得公钥对象
		KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
		return (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
	}

	/**
	 * 得到私钥
	 * 
	 * @param privateKey
	 *            密钥字符串(经过base64编码)
	 * @throws Exception
	 */
	public static RSAPrivateKey getPrivateKey(String privateKey)
			throws NoSuchAlgorithmException, InvalidKeySpecException {
		// 通过PKCS#8编码的Key指令获得私钥对象
		KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
		return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
	}

	/**
	 * 公钥加密
	 * 
	 * @param data
	 * @param publicKey
	 * @return
	 */
	public static String publicEncrypt(String data, RSAPublicKey publicKey) {
		try {
			Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),
					publicKey.getModulus().bitLength()));
		} catch (Exception e) {
			throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
		}
	}

	/**
	 * 私钥解密
	 * 
	 * @param data
	 * @param privateKey
	 * @return
	 */

	public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
		try {
			Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),
					privateKey.getModulus().bitLength()), CHARSET);
		} catch (Exception e) {
			throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
		}
	}

	/**
	 * 私钥加密
	 * 
	 * @param data
	 * @param privateKey
	 * @return
	 */

	public static String privateEncrypt(String data, RSAPrivateKey privateKey) {
		try {
			Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
			cipher.init(Cipher.ENCRYPT_MODE, privateKey);
			return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),
					privateKey.getModulus().bitLength()));
		} catch (Exception e) {
			throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
		}
	}

	/**
	 * 公钥解密
	 * 
	 * @param data
	 * @param publicKey
	 * @return
	 */

	public static String publicDecrypt(String data, RSAPublicKey publicKey) {
		try {
			Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
			cipher.init(Cipher.DECRYPT_MODE, publicKey);
			return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),
					publicKey.getModulus().bitLength()), CHARSET);
		} catch (Exception e) {
			throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
		}
	}

	private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
		int maxBlock = 0;
		if (opmode == Cipher.DECRYPT_MODE) {
			maxBlock = keySize / 8;
		} else {
			maxBlock = keySize / 8 - 11;
		}
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] buff;
		int i = 0;
		try {
			while (datas.length > offSet) {
				if (datas.length - offSet > maxBlock) {
					buff = cipher.doFinal(datas, offSet, maxBlock);
				} else {
					buff = cipher.doFinal(datas, offSet, datas.length - offSet);
				}
				out.write(buff, 0, buff.length);
				i++;
				offSet = i * maxBlock;
			}
		} catch (Exception e) {
			throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
		}
		byte[] resultDatas = out.toByteArray();
		try {
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return resultDatas;
	}
	/**
	 * 将字符串加密为base64
	 * @param before
	 * @return
	 */
	public static String toBase64(byte[] before){
		return (new BASE64Encoder()).encodeBuffer(before);
	}

	/**
	 * 将加密为base64后的字符串解密为原文
	 * @param base64
	 * @return
	 */
	public static byte[] fromBase64(String base64) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(base64);
	}

}

后端调用

/**
 * 使用私钥解密密码
 * */
if(StringUtils.isNotEmpty(user.getPassword())){
	try{
	user.setPassword(RSAUtils.privateDecrypt(user.getPassword(),RSAUtils.getPrivateKey(ConfigConstants.RSA_PRIVATE_KEY)));
	}catch(Exception e){
		//验证码不正确
		logger.debug("RSA密码解密失败");
		throw new BusinessRunTimeException(ExceptionConstants.RSA_DECRYPT_FAILED_CODE,
				ExceptionConstants.RSA_DECRYPT_FAILED_MSG);
	}
}