座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物。
每个人都有惰性,但不断学习新东西是好好生活的根本,共勉!
文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。
加密解密的相关文章参考:
BASE64加密解密
MD5加密
SHA加密解密
RSA加密解密
一、RSA加密简介
RSA是一种公钥密码算法,它的名字是由它的三位开发者,即Ron Rivest、Adi Shamir 和 Leonard Adleman 的姓氏的首字母组成的。RSA可以被用于公钥密码和数字签名。RSA是被研究得最广泛的公钥算法,从提出到现在已近三十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
二、开发环境:
JDK版本:1.8
maven版本:3.9.0
开发工具:IDEA社区版ideaIC-2018.3
项目框架:spring boot 版本为 2.6.3 springboot搭建传送门
三、具体实现
1.引入依赖
所需依赖
无,使用java自带依赖即可实现
2.工具类
RsaUtils.java
package com.rsa.utils; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; 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.ArrayList; import java.util.Base64; import java.util.List; / * @ClassDescription: 加密解密工具类 * @Author:李白 * @Date:2023/3/22 13:05 */ public class RsaUtils {
/ * 常量字符串 */ private static final String RSA = "RSA"; / * 获取密钥对象 * @param keySize RSA算法模长(个人理解应该是模长越大加密安全性越高,但加密过程可能也越长) * @return * @throws NoSuchAlgorithmException */ public static List<Key> getRsaObject(int keySize) throws NoSuchAlgorithmException {
//创建list用来接收公钥对象和私钥对象 List<Key> keyList = new ArrayList<>(); //创建RSA密钥生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA); //设置密钥大小,RSA算法的模长=最大加密数据的大小 keyPairGenerator.initialize(keySize); //调用函数生成公钥私钥对象(以对生成密钥) KeyPair keyPair = keyPairGenerator.generateKeyPair(); //获取公钥放入list keyList.add(keyPair.getPublic()); //获取私钥放入list keyList.add(keyPair.getPrivate()); //返回list return keyList; } / * 生成公钥私钥的字符串 * @param keySize 模长 * @return * @throws NoSuchAlgorithmException */ public static List<String> getRsaKeyString(int keySize) throws NoSuchAlgorithmException {
//创建list用来接收公钥对象和私钥对象 List<String> keyList = new ArrayList<>(); //创建RSA密钥生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA); //设置密钥大小,RSA算法的模长=最大加密数据的大小 keyPairGenerator.initialize(keySize); //调用函数生成公钥私钥对象(以对生成密钥) KeyPair keyPair = keyPairGenerator.generateKeyPair(); //将公钥对象转换为字符串通过base64加密 String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); //将私钥对象转换为字符串通过base64加密 String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); //获取公钥放入list keyList.add(publicKey); //获取私钥放入list keyList.add(privateKey); //返回list return keyList; } / * 通过公钥字符串生成公钥对象(RSAPublicKey类型) * X509EncodeKeySpec方式(字符串公钥转为RSAPublicKey公钥) * @param publicKeyStr 公钥字符串 * @return 返回RSAPublicKey类型的公钥对象 * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static RSAPublicKey getRSAPublicKeyByX509(String publicKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
//密钥工厂创建 KeyFactory keyFactory = KeyFactory.getInstance(RSA); //公钥字符解密为bytes数组 byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr); //公钥字符串转x509 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); //x509转RSAPublicKey return (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec); } / * 通过私钥字符串生成私钥对象(RSAPrivateKey类型) * PKCS8EncodedKeySpec方式(字符串私钥转为RSAPrivateKey公钥) * @param privateKey 私钥字符串 * @return 返回RSAPrivateKey类型的私钥对象 * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static RSAPrivateKey getRSAPrivateKeyByPKCS8(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//密钥工厂创建 KeyFactory keyFactory = KeyFactory.getInstance(RSA); //私钥字符串解密为bytes数组 byte[] keyBytes = Base64.getDecoder().decode(privateKey); //私钥字符串转pkcs8 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); //pkcs8转RSAPrivateKey return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec); } / * 公钥加密 * @param message 需要加密的信息 * @param rsaPublicKey rsa公钥对象 * @return 返回信息被加密后的字符串 * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException * @throws IOException */ public static String encryptByPublicKey(String message, RSAPublicKey rsaPublicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
//RSA加密实例 Cipher cipher = Cipher.getInstance(RSA); //初始化公钥 cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey); //模长转为字节数 int modulusSize = rsaPublicKey.getModulus().bitLength()/8; //PKCS PADDING长度为11字节,解密数据是除去这11byte int maxSingleSize = modulusSize-11; //切分字节数,每段不大于maxSingleSize byte[][] dataArray = splitArray(message.getBytes(), maxSingleSize); //字节数组输出流 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); //分组加密,加密后内容写入输出字节流 for (byte[] s : dataArray){
byteArrayOutputStream.write(cipher.doFinal(s)); } //使用base64将字节数组转为string类型 return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()); } / * 私钥解密密 * @param encryptedMessage 信息加密后的字符串 * @param rsaPrivateKey rsa私钥对象 * @return 返回解密后的字符串 * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException * @throws IOException */ public static String decryptByPrivateKey(String encryptedMessage, RSAPrivateKey rsaPrivateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
//RSA加密实例 Cipher cipher = Cipher.getInstance(RSA); //初始化公钥 cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey); //加密算法模长 int modulusSize = rsaPrivateKey.getModulus().bitLength()/8; byte[] dataBytes = encryptedMessage.getBytes(); //加密做了转码,这里也要用base64转回来 byte[] decodeData = Base64.getDecoder().decode(dataBytes); //切分字节数,每段不大于maxSingleSize byte[][] dataArray = splitArray(decodeData, modulusSize); //字节数组输出流 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); //分组解密,解密后内容写入输出字节流 for (byte[] s : dataArray){
byteArrayOutputStream.write(cipher.doFinal(s)); } //使用base64将字节数组转为string类型 return new String(byteArrayOutputStream.toByteArray()); } / * 按指定长度切分数组 * @param byteArrayInfo 需要切分的byte数组 * @param maxSize 单个字节数组长度 * @return */ private static byte[][] splitArray(byte[] byteArrayInfo, int maxSize){
int dataLen = byteArrayInfo.length; if(dataLen<=maxSize){
return new byte[][]{
byteArrayInfo}; } byte[][] result = new byte[(dataLen-1)/maxSize+1][]; int resultLen = result.length; for (int i = 0; i < resultLen; i++) {
if(i==resultLen-1){
int sLen = dataLen-maxSize*i; byte[] single = new byte[sLen]; System.arraycopy(byteArrayInfo, maxSize*i, single, 0, sLen); result[i] = single; break; } byte[] single = new byte[maxSize]; System.arraycopy(byteArrayInfo, maxSize*i, single, 0, maxSize); result[i] = single; } return result; } }
3.测试类
RsaTest.java
package com.rsa.controller; import com.rsa.utils.RsaUtils; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.IOException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.util.List; / * @ClassDescription: 测试类 * @Author:李白 * @Date:2023/3/22 13:04 */ public class RsaTest {
public static void main(String[]args) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, IOException, InvalidKeyException, InvalidKeySpecException {
String message = "sanQinShan"; System.out.println("加密前的信息内容:"+message); System.out.println("-----------------------RSA密钥对象加密解密--------------------------------"); //生成密钥对象 List<Key> keyList = RsaUtils.getRsaObject(1024); //RSA类型的公钥对象 RSAPublicKey rsaPublicKey = (RSAPublicKey) keyList.get(0); //RSA类型的私钥对象 RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyList.get(1); //通过RSA类型的公钥对象加密信息 String encryptedMsg = RsaUtils.encryptByPublicKey(message, rsaPublicKey); System.out.println("加密后的字符串encryptedMsg:\r\n"+encryptedMsg); //通过RSA类型的私钥对象解密 String decryptedMsg = RsaUtils.decryptByPrivateKey(encryptedMsg, rsaPrivateKey); System.out.println("------"); System.out.println("解密后的字符串decryptedMsg:\r\n"+decryptedMsg); System.out.println(); System.out.println("-----------------------字符串类型的密钥对象转为RSA密钥对象后的加密解密--------------------------"); //生成密钥(字符串类型的密钥) List<String> keyStringList = RsaUtils.getRsaKeyString(1024); //字符串类型的公钥 String publicKeyString = keyStringList.get(0); //字符串类型的私钥 String privateKeyString = keyStringList.get(1); //将字符串类型的公钥私钥转为RSA类型 RSAPublicKey rsaPublicKey1 = RsaUtils.getRSAPublicKeyByX509(publicKeyString); RSAPrivateKey rsaPrivateKey1 = RsaUtils.getRSAPrivateKeyByPKCS8(privateKeyString); //通过字符串公钥转为RSA类型的公钥 加密 String encryptedMsg1 = RsaUtils.encryptByPublicKey(message, rsaPublicKey1); System.out.println("使用字符串转的rsa公钥对象加密后的字符串encryptedMsg1:\r\n"+encryptedMsg1); //通过字符串私钥转为RSA类型的私钥 解密 String decryptedMsg1 = RsaUtils.decryptByPrivateKey(encryptedMsg1, rsaPrivateKey1); System.out.println("------"); System.out.println("使用字符串转的私钥对象解密后的字符串decryptedMsg1:\r\n"+decryptedMsg1); } }
4.对比
控制台输出信息
第一次加密解密后的结果与原信息内容一致
第二次加密解密后的结果与原信息内容一致
验证了两次加密解密的方式都可以正常得到原信息内容
今天的文章 RSA加密解密工具分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/102267.html