RSA加密解密--JAVA实现

不多说,直接上代码。


RSAUtil.java代码:

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
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;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;//这两条指令的执行需引入外部包,外部包分别为commons-codec和commons-io
import org.apache.commons.io.IOUtils;

/**
 * RSA加密与解密(JAVA)
 *
 */
public class RSAUtil {

	public static final String CHARSET = "UTF-8"; // 设置以UTF-8编码
	public static final String RSA_ALGORITHM = "RSA"; // 采用RSA加解密算法
	public static final String PUBLIC_KEY = "publicKey"; //公钥
	public static final String PRIVATE_KEY = "privateKey"; //私钥
	
	/*
	 * 公钥加密
	 */
	public static String publicEncrypt(String data, String publicKey) throws Exception {
		KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
		X509EncodedKeySpec x509Key = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
		RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(x509Key);
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
//		return Base64.encodeBase64String(cipher.doFinal(data.getBytes(CHARSET)));
		return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),pubKey.getModulus().bitLength()));
	}

	/*
	 * 私钥解密
	 */
	public static String privateDecrypt(String data, String privateKey) throws Exception {
		KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
		PKCS8EncodedKeySpec pkcs8Key = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
		RSAPrivateKey priKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8Key);
		Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, priKey);
//		return new String(cipher.doFinal(Base64.decodeBase64(data)));
		return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),priKey.getModulus().bitLength()), CHARSET);
	}
	
	/*
	 * 私钥加密
	 */
	public static String privateEncrypt(String data, String privateKey) throws Exception {
		KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
		PKCS8EncodedKeySpec pkcs8Key = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
		RSAPrivateKey priKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8Key);
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, priKey);
//		return Base64.encodeBase64String(cipher.doFinal(data.getBytes(CHARSET)));
		return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),priKey.getModulus().bitLength()));
	}

	/*
	 * 公钥解密
	 */
	public static String publicDecrypt(String data, String publicKey) throws Exception {
		KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
		X509EncodedKeySpec x509Key = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
		RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(x509Key);
		Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, pubKey);
//		return new String(cipher.doFinal(Base64.decodeBase64(data)));
		return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),pubKey.getModulus().bitLength()), CHARSET);
	}

	public static Map<String, String> createKeys(int keySize) {
		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();
		// 得到密钥对的公钥
		Key publicKey = keyPair.getPublic();
		//JS使用公钥加密时,不能用encodeBase64URLSafeString(原因:加密后的公钥带“_”,加密会返回false)
//		String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
		String publicKeyStr = Base64.encodeBase64String(publicKey.getEncoded());
		// 得到密钥对的私钥
		Key privateKey = keyPair.getPrivate();
		String privateKeyStr = Base64.encodeBase64String(privateKey.getEncoded());
		// 将公钥私钥加入到Map中,方便后面的取出
		Map<String, String> keyMap = new HashMap<String, String>();
		keyMap.put(PUBLIC_KEY, publicKeyStr);
		keyMap.put(PRIVATE_KEY, privateKeyStr);
		return keyMap;
	}

	/*
	 * RSA加密算法对于加密的长度是有要求的。一般来说,加密时,明文长度大于加密钥长度-11时,明文就要进行分段;解密时,密文大于解密钥长度时,
	 * 密文就要进行分段(以字节为单位)
	 */
	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("加解密时异常");
		}
		byte[] resultDatas = out.toByteArray();
		IOUtils.closeQuietly(out);
		return resultDatas;
	}

	public static void main(String[] args) throws Exception {
		Map<String, String> keyMap = RSAUtil.createKeys(1024);
		String publicKey = keyMap.get(PUBLIC_KEY);
		String privateKey = keyMap.get(PRIVATE_KEY);
		System.out.println("公钥: \n" + publicKey);
		System.out.println("私钥:\n" + privateKey);
		System.out.println("\n公钥加密——私钥解密");
		String str = "对称密码,非对称密码,数字签名,Hash函数";
		System.out.println("明文:\n" + str);
		String encodedData = RSAUtil.publicEncrypt(str, publicKey);
		System.out.println("密文:\n" + encodedData);
		String decodedData = RSAUtil.privateDecrypt(encodedData, privateKey);
		System.out.println("解密后文字: \n" + decodedData);
		System.out.println("\n\n~~~~~~~~~~~~~~~~~~~~~~");

		Map<String, String> keyMap2 = RSAUtil.createKeys(1024);
		String publicKey2 = keyMap2.get(PUBLIC_KEY);
		String privateKey2 = keyMap2.get(PRIVATE_KEY);
		System.out.println("公钥2: \n" + publicKey2);
		System.out.println("私钥2:\n" + privateKey2);
		System.out.println("私钥加密——公钥解密");
		String str2 = "对称密码,非对称密码,数字签名,Hash函数~~~~~~";
		System.out.println("明文:\n" + str2);
		String encodedData2 = RSAUtil.privateEncrypt(str2, privateKey2);
		System.out.println("密文:\n" + encodedData2);
		String decodedData2 = RSAUtil.publicDecrypt(encodedData2, publicKey2);
		System.out.println("解密后文字: \n" + decodedData2);
		
		System.out.println("\n\n~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println("\n公钥1加密——私钥2加密--公钥2解密--私钥1解密");
		String str3 = "公钥1加密——私钥2加密--公钥2解密--私钥1解密";
		System.out.println("明文:\n" + str3);
		String encodedData3_1 = RSAUtil.publicEncrypt(str3, publicKey);
		System.out.println("密文1:\n" + encodedData3_1);
		String encodedData3_2 = RSAUtil.privateEncrypt(encodedData3_1, privateKey2);
		System.out.println("密文2:\n" + encodedData3_2);
		String decodedData3_3 = RSAUtil.publicDecrypt(encodedData3_2, publicKey2);
		System.out.println("解密后文字1: \n" + decodedData3_3);
		String decodedData3_4 = RSAUtil.privateDecrypt(decodedData3_3, privateKey);
		System.out.println("解密后文字2: \n" + decodedData3_4);

	}

}

 

JS使用JSA加密解密--后端JAVA解密,请参考:https://blog.csdn.net/cinling123/article/details/103529399

RSA加密、解密、签名、验签的原理及方法,请参考:https://www.cnblogs.com/pcheng/p/9629621.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值