JAVA RSA 加密解密、签名验签 详解

JAVA RSA 加密解密、签名验签 详解

JAVA RSA 加密使用的库是Cipher 和DES一样,更改一下算法就可以了
可以参考:https://blog.csdn.net/qq_21271511/article/details/110529177

javax.crypto.Cipher 是java原生的类库,用来做加密解密的。

官网描述
https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html#method.detail/

此类提供用于加密和解密的密码算法的功能。它构成了Java加密扩展(JCE)框架的核心。

RSA加密解密

因为过程和DES差不多,这里就直接贴代码了,KeyPair 可以直接查一下api就好。

/**
 * @ClassName: RSAUtil
 * @Description: RSA加密解密,加签解签工具类
 * @author 忙碌的菠萝
 * @date 2020年11月27日 下午1:19:55
 *
 */
public class RSAUtil {

/* 
	 * 常见异常对照 
	 * NoSuchAlgorithmException 无此算法,一般是环境问题,编译环境或者运行环境
	 * InvalidKeyException 秘钥非法,秘钥数据或者格式有问题,---begin--- 这种不需要
	 * IllegalBlockSizeException 明文长度非法,秘钥大小决定了可加密明文的长度,长度不符合会报出该异常
	 * BadPaddingException,NoSuchPaddingException 明文数据非法
	 * UnsupportedEncodingException 不支持的编码方式
	 * */

/**
	 * @Fields RSA : RSA算法
	 */
	public static final String RSA = "RSA";
	/**
	 * @Fields SIGN_ALGORITHMS : 签名算法类型
	 */
	public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

	/**
	 * @Fields KEY_SIZE : 密钥长度 于原文长度对应 以及越长速度越慢
	 */
	public static final int KEY_SIZE = 1024;

	/**
	 * @Fields keyMap : 随机产生的公钥与私钥 0-公钥 1-私钥
	 */
	public static Map<Integer, String> keyMap = new HashMap<Integer, String>();

	/**
	 * @Title: genKeyPair
	 * @Description: Generator KeyPair
	 * @param getPrivate() 得到私钥 getPublic() 得到公钥
	 * @return KeyPair
	 * @throws NoSuchAlgorithmException 无此算法
	 */
	public static KeyPair genKeyPair() throws NoSuchAlgorithmException {
		// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
		KeyPairGenerator keyPairGen = null;
		keyPairGen = KeyPairGenerator.getInstance(RSA);
		// 初始化密钥对生成器,密钥大小为96-1024位
		keyPairGen.initialize(KEY_SIZE, new SecureRandom());
		// 生成一个密钥对,保存在keyPair中
		KeyPair keyPair = keyPairGen.generateKeyPair();
		return keyPair;
	}

	/**
	 * @Title: GeneratorKey
	 * @Description: 随机生成密钥对
	 * @param
	 * @return Map<Integer, String> keyMap 秘钥对 0-公钥 1-私钥
	 * @throws Exception
	 */
	public static void GeneratorKey() throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA);
		keyPairGen.initialize(KEY_SIZE, new SecureRandom());
		KeyPair keyPair = keyPairGen.generateKeyPair();
		// 生成秘钥对
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
		// base64转码
		String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
		String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
		keyMap.put(0, publicKeyString); // 0表示公钥
		keyMap.put(1, privateKeyString); // 1表示私钥
	}

/**
	 * @Title: encrypt 
	 * @Description: RSA公钥加密 
	 * @param encryptData 待加密数据
	 * @param publicKey base64编码的公钥 
	 * @return String 加密后的数据 
	 * @throws
	 */
	public static String encrypt(String encryptData, String publicKey) throws Exception {
		try {
			// base64编码的公钥,需要先decode
			byte[] decoded = Base64.decodeBase64(publicKey);
			RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(RSA)
					.generatePublic(new X509EncodedKeySpec(decoded));
			// RSA加密
			Cipher cipher = Cipher.getInstance(RSA);
			cipher.init(Cipher.ENCRYPT_MODE, pubKey);
			String outStr = Base64.encodeBase64String(cipher.doFinal(encryptData.getBytes("UTF-8")));
			return outStr;
		} catch (NoSuchAlgorithmException e) {
			throw new NoSuchAlgorithmException("无此加密算法,请检查环境");
		} catch (NoSuchPaddingException e) {
			throw new NoSuchPaddingException("明文数据未找到");
		} catch (InvalidKeyException e) {
			throw new InvalidKeyException("加密秘钥非法,请检查");
		} catch (IllegalBlockSizeException e) {
			throw new IllegalBlockSizeException("明文长度非法");
		} catch (BadPaddingException e) {
			throw new BadPaddingException("明文数据已损坏");
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("其他错误:", e);
		}
	}

 /**
	* @Title: decrypt
	* @Description: RSA私钥解密
	* @param privateKey base64编码的私钥
	* @return String
	* @throws Exception 解密过程中的异常信息
	*/
	public static String decrypt(String decryptData, String privateKey) throws Exception {
		// 64位解码 加密后的字符串
		byte[] inputByte = Base64.decodeBase64(decryptData.getBytes("utf-8"));
		byte[] decoded = Base64.decodeBase64(privateKey);
		RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(RSA)
				.generatePrivate(new PKCS8EncodedKeySpec(decoded));
		Cipher cipher = Cipher.getInstance(RSA);
		cipher.init(Cipher.DECRYPT_MODE, priKey);
	
		String decryptStr = new String(cipher.doFinal(inputByte));
		return decryptStr;
	}

RSA签名验签

RSA签名验签使用的是 java.security.Signature类

可参考:
https://docs.oracle.com/javase/8/docs/api/java/security/Signature.html

过程也是:获得秘钥 -> getInstance获得实例 -> initSign初始化 -> update数据 -> sign签名

/**
	* @Title: sign
	* @Description: RSA签名
	* @param signData 待签名数据
	* @param privateKey 私钥字符串
	* @return String 签名域
	* @throws
	*/
	public static String sign(String content, String privateKey) throws Exception {
		PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(BASE64.decode(privateKey));
		KeyFactory keyf = KeyFactory.getInstance(RSA);
		PrivateKey priKey = keyf.generatePrivate(priPKCS8);
		java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
		signature.initSign(priKey);
		signature.update(content.getBytes());
		byte[] signed = signature.sign();
		return BASE64.encode(signed);
	}

/**
	* @Title: verify
	* @Description: RSA验签名检查
	* @param content   待签名数据
	* @param sign      签名域
	* @param publicKey base64后的公钥字符串
	* @return boolean 验签结果
	* @throws
	*/
	public static boolean verify(String content, String sign, String publicKey) throws Exception {
		KeyFactory keyFactory = KeyFactory.getInstance(RSA);
		byte[] encodedKey = BASE64.decode(publicKey);
		if (encodedKey == null) {
			return false;
		}
		PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
		// 用私钥对信息生成数字签名
		java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
		signature.initVerify(pubKey);
		signature.update(content.getBytes());
		// 验证方法 返回true则为比对成功
		boolean bverify = signature.verify(BASE64.decode(sign));
		return bverify;
	}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RSA算法是一种非对称加密算法,可以用于加密、数字签名等安全应用。在Java中,可以使用Java内置的加密库实现RSA算法。下面是具体的实现方法: 1. 生成密钥对 使用Java内置的KeyPairGenerator类生成RSA密钥对。示例代码如下: ``` KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); // 指定密钥长度 KeyPair keyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); ``` 2. 加密数据 使用公钥加密数据。示例代码如下: ``` Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedData = cipher.doFinal(plainData); ``` 其中,plainData是要加密的数据。 3. 解密数据 使用私钥解密数据。示例代码如下: ``` Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedData = cipher.doFinal(encryptedData); ``` 其中,encryptedData是加密后的数据。 4. 数字签名 使用私钥签名数据,使用公钥签名。示例代码如下: ``` Signature signature = Signature.getInstance("SHA256withRSA"); signature.initSign(privateKey); signature.update(data); byte[] signatureData = signature.sign(); signature.initVerify(publicKey); signature.update(data); boolean verified = signature.verify(signatureData); ``` 其中,data是要签名的数据,signatureData是签名后的数据。 以上就是Java实现RSA算法的具体方法。需要注意的是,RSA算法的安全性依赖于密钥长度,一般建议使用至少2048位的密钥。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忙碌的菠萝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值