RSA 分段加解密【解决“不正确的长度”的异常】
RSA 是常用的非对称加密算法。最近使用时却出现了“不正确的长度”的异常,研究发现是由于待加密的数据超长所致。
.NET Framework 中提供的 RSA 算法规定:
待加密的字节数不能超过密钥的长度值除以 8 再减去 11(即:RSACryptoServiceProvider.KeySize / 8 - 11),而加密后得到密文的字节数,正好是密钥的长度值除以 8(即:RSACryptoServiceProvider.KeySize / 8)。
所以,如果要加密较长的数据,则可以采用分段加解密的方式,实现方式如下:
namespace Macroresolute.RSACryptoService
{
public static class RSACrypto
{
private static readonly Encoding Encoder = Encoding.UTF8; public static String Encrypt(this String plaintext)
{
X509Certificate2 _X509Certificate2 = RSACrypto.RetrieveX509Certificate();
using (RSACryptoServiceProvider RSACryptography = _X509Certificate2.PublicKey.Key as RSACryptoServiceProvider)
{
Byte[] PlaintextData = RSACrypto.Encoder.GetBytes(plaintext);
int MaxBlockSize = RSACryptography.KeySize / - ; //加密块最大长度限制 if (PlaintextData.Length <= MaxBlockSize)
return Convert.ToBase64String(RSACryptography.Encrypt(PlaintextData, false)); using (MemoryStream PlaiStream = new MemoryStream(PlaintextData))
using (MemoryStream CrypStream = new MemoryStream())
{
Byte[] Buffer = new Byte[MaxBlockSize];
int BlockSize = PlaiStream.Read(Buffer, , MaxBlockSize); while (BlockSize > )
{
Byte[] ToEncrypt = new Byte[BlockSize];
Array.Copy(Buffer, , ToEncrypt, , BlockSize); Byte[] Cryptograph = RSACryptography.Encrypt(ToEncrypt, false);
CrypStream.Write(Cryptograph, , Cryptograph.Length); BlockSize = PlaiStream.Read(Buffer, , MaxBlockSize);
} return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
}
}
} public static String Decrypt(this String ciphertext)
{
X509Certificate2 _X509Certificate2 = RSACrypto.RetrieveX509Certificate();
using (RSACryptoServiceProvider RSACryptography = _X509Certificate2.PrivateKey as RSACryptoServiceProvider)
{
Byte[] CiphertextData = Convert.FromBase64String(ciphertext);
int MaxBlockSize = RSACryptography.KeySize / ; //解密块最大长度限制 if (CiphertextData.Length <= MaxBlockSize)
return RSACrypto.Encoder.GetString(RSACryptography.Decrypt(CiphertextData, false)); using (MemoryStream CrypStream = new MemoryStream(CiphertextData))
using (MemoryStream PlaiStream = new MemoryStream())
{
Byte[] Buffer = new Byte[MaxBlockSize];
int BlockSize = CrypStream.Read(Buffer, , MaxBlockSize); while (BlockSize > )
{
Byte[] ToDecrypt = new Byte[BlockSize];
Array.Copy(Buffer, , ToDecrypt, , BlockSize); Byte[] Plaintext = RSACryptography.Decrypt(ToDecrypt, false);
PlaiStream.Write(Plaintext, , Plaintext.Length); BlockSize = CrypStream.Read(Buffer, , MaxBlockSize);
} return RSACrypto.Encoder.GetString(PlaiStream.ToArray());
}
}
} private static X509Certificate2 RetrieveX509Certificate()
{
return null; //检索用于 RSA 加密的 X509Certificate2 证书
}
}
}
注:以上加密方法返回的字符串类型为原始的 Base-64 ,若要用于 URL 传输,需另行处理!
分享自:http://www.cnblogs.com/zys529/archive/2012/05/24/2516539.html
RSA 分段加解密【解决“不正确的长度”的异常】的更多相关文章
- C# RSA 分段加解密
RSA加解密: 1024位的证书,加密时最大支持117个字节,解密时为128:2048位的证书,加密时最大支持245个字节,解密时为256. 加密时支持的最大字节数:证书位数/8 -11(比如:204 ...
- Java RSA 分段加解密
RSA加解密: 1024位的证书,加密时最大支持117个字节,解密时为128:2048位的证书,加密时最大支持245个字节,解密时为256. 加密时支持的最大字节数:证书位数/8 -11(比如:204 ...
- 偏前端 + rsa加解密 + jsencrypt.min.js--(新增超长字符分段加解密)
<html> <head> <title>JavaScript RSA Encryption</title> <meta charset=&quo ...
- RSA签名,加解密处理核心文件
import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.secur ...
- [Python3] RSA的加解密和签名/验签实现 -- 使用pycrytodome
Crypto 包介绍: pycrypto,pycrytodome 和 crypto 是一个东西,crypto 在 python 上面的名字是 pycrypto 它是一个第三方库,但是已经停止更新,所以 ...
- php rsa 非对称加解密类
<?php header("Content-Type: text/html;charset=utf-8"); /* 生成公钥.私钥对,私钥加密的内容能通过公钥解密(反过来亦可 ...
- 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)
两种原因: 第一种为程序的运行以平台系统位数不匹配,第二种则是该死的VS整出来的... 一般在下面三种情景下会发生. 1.64位系统上C#调用32位的C++ *.dll 2.64位系统上IIS发布含有 ...
- sqllite 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)
试图加载格式不正确的程序. (异常来自 HRESULT:0x8007000B) 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细 ...
- asp.net 报错 SAP 报错 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)
“/”应用程序中的服务器错误. 试图加载格式不正确的程序. (异常来自 HRESULT:0x8007000B) 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该 ...
随机推荐
- [C程序设计基础]快速排序
//从大到小排序 ///三个参数 a要排序的 数组, l扫左边的 r扫右边 void quickSort(int a[],int l, int r){ /// 左边要小于 右边才有意义 if (l & ...
- 常用的Lambda表达式
Java 8 引入Lambda表达式,对于Java开发人员来说是一大福利,简化了代码,提高了开发效率. 本文主要讲解日常开发中使用频率比较高的几类Lambda表达式. 集合 Lambda表达式的引入 ...
- 利用"SQL"语句自动生成序号的两种方式
1.首先,我们来介绍第一种方式: ◆查询的SQL语句如下: select row_number() over (order by name) as rowid, sysobjects.[id] fro ...
- System.out.println()和System.err.println()
在一次笔试中遇到了一个System.err.println()的输出,之前没有见过,回来查一查,自己还是见识太短,来补充一下. 首先看一看jdk中 来一个简单的实验 第一次显示 第二次显示 1. 发现 ...
- springmvc注解方式
https://www.cnblogs.com/shanheyongmu/p/5865589.html
- Java 构造器 遇到多个构造器时要考虑用构建器
静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数. 当一个类中有若干个必选属性和多个可选属性时,采用重叠构造器模式.JavaBeans模式或者Builder模式,但各有优劣. 当 ...
- jquery移除事件,绑定事件,触发事件
$('.gcddfadf-btn-pay').unbind('click');//移除绑定事件 $('.gcddfadf-btn-pay').bind('click',function(){});// ...
- Mac redis入门
Mac redis入门 一.Redis简介 Redis是开源的key-value数据库,运行在内存中,但可以把数据持久化存到磁盘.Redis具有极高的性能,也为各种语言提供了丰富的接口,因此有着广泛的 ...
- list-循环小练习(作业已交未交)
报错 list index out of range : 超出下标 这个错误是因为在写stus列表的时候写成了如下stus=['小花,未交'] ,但是取下标的时候取的是stus[1]:实际该列表中 ...
- Jmeter接口测试实例3-登录
Jmeter实例3:登录 添加http协议—添加IP.路径.方法,察看结果树,运行 登录成功