在日常的业务逻辑中,难免会遇到需要加密的时候,而常见的MD5加密因为是单向加密并且不可逆,导致应用场景非常的少,而这个时候,RSA对称加密就诞生了。
RSA加密的逻辑是,生成一个公钥和私钥。
你可以选择公钥加密,私钥解密,也可以选择 私钥加密,公钥解密。
一般情况下 都是公钥加密,和私钥解密。

一,简单的应用

1. Java生成密钥

/*** 初始化密钥对** @return Map 甲方密钥的Map*/public static Map<String, Object> initKey() throws Exception {//实例化密钥生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");//初始化密钥生成器//密钥长度,DH算法的默认密钥长度是1024//密钥长度必须是64的倍数,在512到65536位之间keyPairGenerator.initialize(4096);//生成密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();//甲方公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//甲方私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//将密钥存储在map中Map<String, Object> keyMap = new HashMap<String, Object>();//公钥keyMap.put("RSAPublicKey", publicKey);//私钥keyMap.put("RSAPrivateKey", privateKey);return keyMap;}

生成密钥对的方式有很多,这里只是简单的说明一下。

2. 公钥加密方法

/*** 公钥加密** @param data 待加密数据* @param key       密钥* @return byte[] 加密数据*/public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {//实例化密钥工厂KeyFactory keyFactory = KeyFactory.getInstance("RSA");//初始化公钥//密钥材料转换X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);//产生公钥PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);//数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, pubKey);return cipher.doFinal(data);}

3. 私钥解密方法

/*** 私钥解密** @param data 待解密数据* @param key  密钥* @return byte[] 解密数据*/public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {//取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance("RSA");//生成私钥PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);//数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}

4. 运行

public static void main(String[] args) throws Exception {//初始化密钥//生成密钥对Map<String, Object> keyMap = RSACoder.initKey();//公钥byte[] publicKey = RSACoder.getPublicKey(keyMap);//私钥byte[] privateKey = RSACoder.getPrivateKey(keyMap);System.out.println("公钥:/n" + Base64.encodeBase64String(publicKey));System.out.println("私钥:/n" + Base64.encodeBase64String(privateKey));System.out.println("================密钥对构造完毕,开始进行加密数据的传输=============");String str = "情人怨遥夜,竟兮起相思。";System.out.println("原文:"+str);//使用公钥对数据进行加密byte[] code2 = RSACoder.encryptByPublicKey(str.getBytes(), publicKey);System.out.println("===========使用公钥对数据进行加密==============");System.out.println("加密后的数据:" + Base64.encodeBase64String(code2));System.out.println("===========使用私钥对数据进行解密==============");//甲方使用私钥对数据进行解密byte[] decode2 = RSACoder.decryptByPrivateKey(code2, privateKey);System.out.println("解密后的数据:" + new String(decode2));}

运行结果:

这个时候 基本的加密解密就完成了。

二,问题解答

1. 数据量太大,加密解密报错。

  1. 原因
    解密有长度限制,长度限制为密钥长度/8;
    一般来说密钥长度为1024,加密长度为 128 ,加密长度为 117 ,如果字符超过这个数量就会报错。
  2. 解决方案
    采用分段加密解密,计算出来需要加密数据的长度
    以128分割成多个数组进行加密,
    以117分割成多个数组进行解密

2. 分段加密解密后出现部分中文乱码

  1. 原因,加密和解密数据都是要转成byte[] 类型的,字符串占字节为3,所以在分割字节的时候,将一个汉字分割成了两个数组的结尾和开头,这样就会出现乱码的情况。

3. 加密后密文格式不是是这个格式的

chgHTkMMibvlnbb+50AhHQyCXxrW9Wgjm34p/sCEtAlflU037by5t5dL3w01UIm99VOzfqcZUul7HLdqFanZcCXA5G3ILwZvNZJu19OR5svFS8af6RikS8vkr+26P5yJwD2BfxaY/DDeh3dZGxEkrr/p842vgDw0JalqPRq6C/e5DdHScHKzxyinEq6RZjLEP7m4KwztuSygzRXXgzG/eVphO+kVMiCF5Q7OXbhEIOQLsmTVa530dW3/MQ6BALgIwYx8jMg31rMSRuSgWNVGu5yupi71fA4rDMHK23rnBBDc0bPj+7NdqBXj+AsFSlc+fpWo/+h5Orqhmdk6jm5NCfsXW9Hn+fBLIul/pIQryY9XMoA0nAdNrMarX8HGkQQi40L58r4N8X6RZL369n9b/ytGdctZ6A1MI83hn4r2mhJU43pMw7ce+h9tvye3/ctP4J1uJLcoedThScgR9WaO5GFWk7mgalyAOSlPYiVr+T1SXBnrh+zYH68T++IKyWxt9AfSghntYDt9Oa09wf0Rdj1lUPQsxpo8VVHd9WuCTlLZR3J1Ym12pO9vgSUXbSPpBrrPef94ZwbWvjGMtpYGKQiR7d5FAk3qTOT/qodIxQjWd/mGk+5DSB8hh6yHqdwKHPzG81ibLrSyK/1e7EXYuGB2fXYdlJPlPxhfI5r1Qtc=
  1. 原因:密文格式不一样的原因是你的原数据的编码格式的问题,我全部采用的utf-8;

附上我的工具类

package com.tysu.mall.core.util;/*** 创建时间:2019/01/10* 创建人:Administrator* 描述:*/import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
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.Base64;
import java.util.HashMap;
import java.util.Map;/*** 1、公钥加密,私钥解密用于信息加密* 2、私钥加密,公钥解密用于数字签名*/
public class RsaTool{//定义加密方式public static final String KEY_RSA = "RSA";//定义公钥关键词public static final String KEY_RSA_PUBLICKEY = "RSAPublicKey";//定义私钥关键词public static final String KEY_RSA_PRIVATEKEY = "RSAPrivateKey";//定义签名算法private final static String KEY_RSA_SIGNATURE = "MD5withRSA";/*** *** RSA最大加密大小*/private final static int MAX_ENCRYPT_BLOCK = 117;/*** *** RSA最大解密大小*/private final static int MAX_DECRYPT_BLOCK = 128;/*** 生成公私密钥对*/public static Map<String, Object> init(){Map<String, Object> map = null;try{KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);//设置密钥对的bit数,越大越安全,但速度减慢,一般使用512或1024generator.initialize(1024);KeyPair keyPair = generator.generateKeyPair();// 获取公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();// 获取私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();// 将密钥对封装为Mapmap = new HashMap<String, Object>();map.put(KEY_RSA_PUBLICKEY, publicKey);map.put(KEY_RSA_PRIVATEKEY, privateKey);} catch (NoSuchAlgorithmException e){e.printStackTrace();}return map;}/*** 获取Base64编码的公钥字符串*/public static String getPublicKey(Map<String, Object> map){String str = "";Key key = (Key) map.get(KEY_RSA_PUBLICKEY);str = encryptBase64(key.getEncoded());return str;}/*** 获取Base64编码的私钥字符串*/public static String getPrivateKey(Map<String, Object> map){String str = "";Key key = (Key) map.get(KEY_RSA_PRIVATEKEY);str = encryptBase64(key.getEncoded());return str;}/*** BASE64 解码** @param key 需要Base64解码的字符串* @return 字节数组*/public static byte[] decryptBase64(String key){return Base64.getDecoder().decode(key);}/*** BASE64 编码** @param key 需要Base64编码的字节数组* @return 字符串*/public static String encryptBase64(byte[] key){return new String(Base64.getEncoder().encode(key));}/*** 公钥加密** @param encryptingStr* @param publicKeyStr* @return*/public static String encryptByPublicKey(String encryptingStr, String publicKeyStr){try{// 将公钥由字符串转为UTF-8格式的字节数组byte[] publicKeyBytes = decryptBase64(publicKeyStr);// 获得公钥X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);// 取得待加密数据byte[] data = encryptingStr.getBytes("UTF-8");KeyFactory factory;factory = KeyFactory.getInstance(KEY_RSA);PublicKey publicKey = factory.generatePublic(keySpec);// 对数据加密Cipher cipher = Cipher.getInstance(factory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);// 返回加密后由Base64编码的加密信息int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offSet > 0){if (inputLen - offSet > MAX_ENCRYPT_BLOCK){cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);} else{cache = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_ENCRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();return encryptBase64(decryptedData);} catch (Exception e){e.printStackTrace();}return null;}/*** 私钥解密** @param encryptedStr* @param privateKeyStr* @return*/public static String decryptByPrivateKey(String encryptedStr, String privateKeyStr){try{// 对私钥解密byte[] privateKeyBytes = decryptBase64(privateKeyStr);// 获得私钥PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);// 获得待解密数据byte[] data = decryptBase64(encryptedStr);KeyFactory factory = KeyFactory.getInstance(KEY_RSA);PrivateKey privateKey = factory.generatePrivate(keySpec);// 对数据解密Cipher cipher = Cipher.getInstance(factory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);// 返回UTF-8编码的解密信息int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offSet > 0){if (inputLen - offSet > MAX_DECRYPT_BLOCK){cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);} else{cache = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();return new String(decryptedData, "UTF-8");} catch (Exception e){e.printStackTrace();}return null;}/*** 私钥加密** @param encryptingStr* @param privateKeyStr* @return*/public static String encryptByPrivateKey(String encryptingStr, String privateKeyStr){try{byte[] privateKeyBytes = decryptBase64(privateKeyStr);// 获得私钥PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);// 取得待加密数据byte[] data = encryptingStr.getBytes("UTF-8");KeyFactory factory = KeyFactory.getInstance(KEY_RSA);PrivateKey privateKey = factory.generatePrivate(keySpec);// 对数据加密Cipher cipher = Cipher.getInstance(factory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);// 返回加密后由Base64编码的加密信息int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offSet > 0){if (inputLen - offSet > MAX_ENCRYPT_BLOCK){cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);} else{cache = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_ENCRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();return encryptBase64(decryptedData);} catch (Exception e){e.printStackTrace();}return null;}/*** 公钥解密** @param encryptedStr* @param publicKeyStr* @return*/public static String decryptByPublicKey(String encryptedStr, String publicKeyStr){try{// 对公钥解密byte[] publicKeyBytes = decryptBase64(publicKeyStr);// 取得公钥X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);// 取得待加密数据byte[] data = decryptBase64(encryptedStr);KeyFactory factory = KeyFactory.getInstance(KEY_RSA);PublicKey publicKey = factory.generatePublic(keySpec);// 对数据解密Cipher cipher = Cipher.getInstance(factory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);// 返回UTF-8编码的解密信息int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offSet > 0){if (inputLen - offSet > MAX_DECRYPT_BLOCK){cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);} else{cache = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();return new String(decryptedData, "UTF-8");} catch (Exception e){e.printStackTrace();}return null;}/*** 用私钥对加密数据进行签名** @param encryptedStr* @param privateKey* @return*/public static String sign(String encryptedStr, String privateKey){String str = "";try{//将私钥加密数据字符串转换为字节数组byte[] data = encryptedStr.getBytes();// 解密由base64编码的私钥byte[] bytes = decryptBase64(privateKey);// 构造PKCS8EncodedKeySpec对象PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);// 指定的加密算法KeyFactory factory = KeyFactory.getInstance(KEY_RSA);// 取私钥对象PrivateKey key = factory.generatePrivate(pkcs);// 用私钥对信息生成数字签名Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);signature.initSign(key);signature.update(data);str = encryptBase64(signature.sign());} catch (Exception e){e.printStackTrace();}return str;}/*** 校验数字签名** @param encryptedStr* @param publicKey* @param sign* @return 校验成功返回true,失败返回false*/public static boolean verify(String encryptedStr, String publicKey, String sign){boolean flag = false;try{//将私钥加密数据字符串转换为字节数组byte[] data = encryptedStr.getBytes();// 解密由base64编码的公钥byte[] bytes = decryptBase64(publicKey);// 构造X509EncodedKeySpec对象X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);// 指定的加密算法KeyFactory factory = KeyFactory.getInstance(KEY_RSA);// 取公钥对象PublicKey key = factory.generatePublic(keySpec);// 用公钥验证数字签名Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);signature.initVerify(key);signature.update(data);flag = signature.verify(decryptBase64(sign));} catch (Exception e){e.printStackTrace();}return flag;}
}

RSA加密解密,分段加密,分段解密,部分汉字乱码详解相关推荐

  1. 网络知识详解之:HTTPS通信原理剖析(对称、非对称加密、数字签名、数字证书)

    网络知识详解之:HTTPS通信原理剖析(对称.非对称加密.数字签名.数字证书) 计算机网络相关知识体系详解 网络知识详解之:TCP连接原理详解 网络知识详解之:HTTP协议基础 网络知识详解之:HTT ...

  2. 密码学:RSA加密算法详解

    概述 本文旨在说明RSA加密算法的原理及实现,而其相关的数学部分的证明则不是本文内容. 版权说明 著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Q-WHai 发表日期: ...

  3. java rsa加密解密_前端实现对请求参数进行RSA加密amp;解密,针对字符串过长进行分段加密amp;分段解密的处理...

    前言 在需求开发中,为了安全起见,我们都会难免遇到需要对一些敏感参数进行加密或者解密.所以,今天给大家分享的就是使用jsencrypt对请求参数进行RSA加密与解密,发这篇文章其实主要因为近期我的一位 ...

  4. java RSA加密解密实现(含分段加密)

    该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detail/centralperk/50255 ...

  5. RSA分段加密分段解密以及密钥与.Net的转化

    代码中采用了Base64 对应的Maven仓库地址 <!-- http://mvnrepository.com/artifact/net.iharder/base64 --> <de ...

  6. RSA分段加密/解密 nodejs 和java联调

    RSA分段加密/解密 nodejs 和java联调 文章目录 RSA分段加密/解密 nodejs 和java联调 1 nodejs 环境 1.1 axios配置 1.2 API接口 1.3 业务 1. ...

  7. c语言 rsa算法 分段,python3 实现RSA算法分段加密解密

    参考博客地址: https://blog.csdn.net/qq_33414271/article/details/78424951 https://www.cnblogs.com/piperck/p ...

  8. Java实现RSA分段加密解密

    本文完成的是公钥加密,私钥解密(私钥加密公钥解密是一样的). 注意点: 秘钥生成的格式不同,使用算法也不同,公钥是X509EncodedKeySpec,私钥是PKCS8EncodedKeySpec. ...

  9. Python | Python 实现RSA加解密 验签 无 长度限制 加密解密, 分段加密

    系列文章目录 Python | Flask 解决跨域问题 文章目录 系列文章目录 为什么要分段加密 代码示例 测试 测试结果 为什么要分段加密 加密的字段长短规则如下: 加密的 plaintext 最 ...

最新文章

  1. Matlab数据的可视化 -- 茎干图
  2. css怎样通过超链接更改背景,css超链接的底色如何设置
  3. wxWidgets:TextCtrl示例
  4. python format函数实例_python中强大的format函数实例详解
  5. 2016蓝桥杯省赛---java---B---1(煤球数目)
  6. 计算机基础及ms应用在线,全国一级计算机基础及MS Office应用课件 (2).pdf
  7. java 不执行构造函数_函数作为构造函数执行,但不作为函数执行
  8. linux课堂笔记(8)
  9. Linux版本tomcat下载及安装
  10. 考研编程练习----畅通工程
  11. php空间 数据库设计,php进阶之数据库设计/ 选择合适的表引擎
  12. c语言 两个文件相似度比较,比较两文件的相似度(比较中文)
  13. 开源软件的安全性风险_认真对待开源安全性
  14. 开源新作!抖音四面被拒,再战头条终获offer,一文搞懂
  15. WorkManager
  16. 关于Linux的本地回环路由lo [127.0.0.1 ]
  17. 【C语言】(百合花)水仙花数的算法思考习题4-6 水仙花数
  18. 如何言语上更好的激励别人?
  19. codeforces Mafia
  20. 【路径规划】基于蚁群算法求解机器人栅格地图路径规划matlab代码

热门文章

  1. 【noip】HankSon的趣味题
  2. Linux pipe详解
  3. rpm和yum/dnf 安装方式与区别
  4. 【每天一个java设计模式(二十三)】 - 访问者模式
  5. 蒲福风力等级c语言编程,蒲福风力等级表.doc
  6. 《预见未来》——观后感
  7. 一次函数的概念、性质及函数图象特征
  8. OO六大设计原则最全分析总结篇
  9. location.host 与 location.hostname 的区别
  10. UOS/Deepin 关于kwin的问题