Java RSA分段加密
我们通过Java进行RSA加密的时候,可能会出现如下问题:
/**
* 私钥加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
String KEY_ALGORITHM = "RSA"; // 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
那么要怎么解决呢,就是分段加密,代码如下:
package cn.gdsoft; 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.*; import javax.crypto.Cipher; public class RSAUtils {
/** */
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA"; /** */
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** */
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey"; /** */
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey"; /** */
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117; /** */
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128; /** */
/**
* <p>
* 生成密钥对(公钥和私钥)
* </p>
*
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
} /** */
/**
* <p>
* 用私钥对信息生成数字签名
* </p>
*
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64.getEncoder().encodeToString(signature.sign());
} /** */
/**
* <p>
* 校验数字签名
* </p>
*
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
*
* @return
* @throws Exception
*
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64.getDecoder().decode(sign));
} /** */
/**
* <P>
* 私钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
} /** */
/**
* <p>
* 公钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
} /** */
/**
* <p>
* 公钥加密
* </p>
*
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
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[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
} /** */
/**
* <p>
* 私钥加密
* </p>
*
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
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[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
} /** */
/**
* <p>
* 获取私钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64.getEncoder().encodeToString(key.getEncoded());
} /** */
/**
* <p>
* 获取公钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64.getEncoder().encodeToString(key.getEncoded());
} }
主方法的代码如下:
public static void main(String[] args) throws UnsupportedEncodingException, Exception {
// 私钥
String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIKVVUQ3w1t+cK/8ZrzBbZ+hNITJ7peTGjvocwtIb1ENrdhqhpdsReymMAfwJ8oOGRLbmaRoHs3u0IeiFh3JPZif8MhvT5UPK/NNUB7W3qHk2NcVWajcDlgYRTcIZ9t83pW90vuXKFP4CLoNWllooLxoZumjOGN523Cihh4XxkxVAgMBAAECgYAwcelnvQ5Xb8GrsIaG6XXbfmlnCClhh1v4tMSVf4J4vgvsWZzkKXGJmaABGeoRDojj05+c/FnNSZeIciwlUcbtRGNJNd/3i1+BRMXdaDs3RBEI7oxLPrMY7US56TVHschZjaX2elenvapEScv+9lJVsRH42KDVGSd5csRG5ZOb4wJBALb9SLcPYEKYx02j5fkvXRNQoVdpWTWSrdb1xxvGlouJGzIR4Z45CN9+qaHhFfYzZ9haRRKD2YR1qaoBHohRKUsCQQC2rz4nNHTi6BqFz/zZUauPCu8yJs/lK36z6bqr26YrBGwCrj9qgXvymPaeFY92xcD6FM3FG1kj8jKpAaVKWXzfAkAPOcHsIWZkBCxJJIMFGdDHw6S5DjXzBDJcuXSIthxendjacKxyKtK3LeXVZ1IZeyt/z/sBUGEv6U5lq9QriX1DAkAxp14YX9ypU/bpigeqtdUQkyNCmWQGYRUWJ6AyWAhJRvFopR3dgAZFgSf+/dM5sDRshL0NJwrKh2kXoLfhhoM3AkBsWyZK+eIxKRMqqCDAPEyZfD9/4GGxwaY2D0Ghl+rzTk9cP30r5nG/DSzbmyAA4J7liVWMWKL0Rs0X+xkUR87r";
String content = "try { if (string.IsNullOrEmpty(qxdm)) { return Content(new ResponseData(false, "请确保参数[qxdm]存在不为空").ToString()); } if (pageSize <= 0) { return Content(new ResponseData(false, "请确保参数[pageSize]存在且大于0").ToString()); } if (pageIndex <= 0) { return Content(new ResponseData(false, "请确保参数[pageIndex]存在且大于0").ToString()); } var dic = new YwlbWatchBLL().GetTimeoutList(qxdm, pageIndex, pageSize); var res = new ResponseData(true, "", dic); return Content(res.ToString());" ; byte[] res = RSAUtils.encryptByPrivateKey(content.getBytes("utf-8"), privateKey); System.out.println("加密后的数据是:");
System.out.println(Base64.getEncoder().encodeToString(res));
}
这样就可以实现RSA超过117byte长度的数据加密了
Java RSA分段加密的更多相关文章
- JAVA RSA非对称加密详解[转载]
一.概述1.RSA是基于大数因子分解难题.目前各种主流计算机语言都支持RSA算法的实现2.java6支持RSA算法3.RSA算法可以用于数据加密和数字签名4.RSA算法相对于DES/AES等对称加密算 ...
- JAVA RSA私钥 加密(签名) 对应 C# RSA私钥 加密(签名)
非对称密钥RSA算法加解密在C#和Java之间交互的问题,这两天看了很多其他人写的文章,碰到了几个问题,最终解决问题. 参考地址:http://xw-z1985.iteye.com/blog/1837 ...
- Java RSA 分段加解密
RSA加解密: 1024位的证书,加密时最大支持117个字节,解密时为128:2048位的证书,加密时最大支持245个字节,解密时为256. 加密时支持的最大字节数:证书位数/8 -11(比如:204 ...
- openssl Rsa 分段加密解密
密钥长度 1024 openssl genrsa -out rsa_private_key.pem openssl rsa -in rsa_private_key.pem -pubout -out r ...
- java RSA加密解密实现(含分段加密)
该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detail/centralperk/50255 ...
- java RSA加密解密--转载
原文地址:http://www.blogjava.net/icewee/archive/2012/05/19/378570.html 该工具类中用到了BASE64,需要借助第三方类库:javabase ...
- RSA非对称加密简析-java
1 非对称加密算法 1.1 概述 1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这 ...
- 【转】 java RSA加密解密实现
[转] java RSA加密解密实现 该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detai ...
- RSA非对称加密(java实例代码)
使用RSA对WebService传递的信息加密解密的基本思想是:服务器端提供一个WebService方法String getServerPublicKey(),客户端可以以此得到服务器端的公钥,然后使 ...
随机推荐
- NodeJS 开发博客(四) 日志及安全攻击
node 操作文件: const fs = require('fs'); const path = require('path'); const filename = path.resolve(__d ...
- sudo 以管理员身份运行脚本--tee方式记录脚本日志
说明:当运行脚本时,常遇到权限不足等,可以用以上方法来以管理员权限运行 1.编辑/etc/sudoers (注意,这里使用 visudo 而不是 vi 来设置.) 2.visudo或 给与/etc/s ...
- [2019南昌邀请赛网络赛D][dp]
https://nanti.jisuanke.com/t/38223 Xiao Ming recently indulges in match stick game and he thinks he ...
- js中event.preventDefault()和 event.stopPropagation( ) 方法详解
event.preventDefault() 1.首先event.preventDefault()是通知浏览器不要执行与事件关联的默认动作,例如: 这里a标签的默认事件是跳转,这里我们告诉浏览器取消 ...
- E:nth-last-child(n)
E:nth-last-child(n) 语法: E:nth-last-child(n) { sRules } 说明: 匹配父元素的倒数第n个子元素E,假设该子元素不是E,则选择符无效.大理石平台维修 ...
- LOJ P10116 清点人数 题解
每日一题 day13 打卡 Analysis 用简单的树状数组维护单点修改和查询就行了 #include<iostream> #include<cstdio> #include ...
- leetcode解题报告(16):Move Zeroes
描述 Given an array nums, write a function to move all 0's to the end of it while maintaining the rela ...
- NetworkX系列教程(1)-创建graph
小书匠Graph图论 研究中经常涉及到图论的相关知识,而且常常面对某些术语时,根本不知道在说什么.前不久接触了NetworkX这个graph处理工具,发现这个工具已经解决绝大部分的图论问题(也许只是我 ...
- php 多维数组,根据某个特定字段过滤重复值
//假如 数据是这样的$arr=[ [ 'goods_name'=>'xxx', 'goods_id'=>111,],[ 'goods_name'=>'xxx', 'goods_id ...
- [Go] 基础系列一: for-select中的break、continue和return
break select中的break,类似c系列中的break,break后的语句不执行 for和select一同使用,有坑 break只能跳出select,无法跳出for package test ...