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 分段加解密【解决“不正确的长度”的异常】的更多相关文章

  1. C# RSA 分段加解密

    RSA加解密: 1024位的证书,加密时最大支持117个字节,解密时为128:2048位的证书,加密时最大支持245个字节,解密时为256. 加密时支持的最大字节数:证书位数/8 -11(比如:204 ...

  2. Java RSA 分段加解密

    RSA加解密: 1024位的证书,加密时最大支持117个字节,解密时为128:2048位的证书,加密时最大支持245个字节,解密时为256. 加密时支持的最大字节数:证书位数/8 -11(比如:204 ...

  3. 偏前端 + rsa加解密 + jsencrypt.min.js--(新增超长字符分段加解密)

    <html> <head> <title>JavaScript RSA Encryption</title> <meta charset=&quo ...

  4. RSA签名,加解密处理核心文件

    import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.secur ...

  5. [Python3] RSA的加解密和签名/验签实现 -- 使用pycrytodome

    Crypto 包介绍: pycrypto,pycrytodome 和 crypto 是一个东西,crypto 在 python 上面的名字是 pycrypto 它是一个第三方库,但是已经停止更新,所以 ...

  6. php rsa 非对称加解密类

    <?php header("Content-Type: text/html;charset=utf-8"); /* 生成公钥.私钥对,私钥加密的内容能通过公钥解密(反过来亦可 ...

  7. 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)

    两种原因: 第一种为程序的运行以平台系统位数不匹配,第二种则是该死的VS整出来的... 一般在下面三种情景下会发生. 1.64位系统上C#调用32位的C++ *.dll 2.64位系统上IIS发布含有 ...

  8. sqllite 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)

    试图加载格式不正确的程序. (异常来自 HRESULT:0x8007000B) 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细 ...

  9. asp.net 报错 SAP 报错 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)

    “/”应用程序中的服务器错误. 试图加载格式不正确的程序. (异常来自 HRESULT:0x8007000B) 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该 ...

随机推荐

  1. Windows上搭建安卓的Java开发环境

    下载安装JDK path的系统变量增加值(示例): D:\Program Files\Java\jdk1.8.0_25\bin同理为名为classpath的系统变量增加值(示例:没有的话可以新建)D: ...

  2. 并发编程之I/O模型

    1.I/O模型介绍 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个 ...

  3. C# 使用PrintDocument 绘制表格 完成 打印预览

    C# 使用PrintDocument 绘制表格 完成 打印预览 DataTable   经过不断的Google与baidu,最终整理出来的打印类 主要是根据两个参考的类组合而成,稍微修改了一下,参考代 ...

  4. 潭州课堂25班:Ph201805201 django 项目 第八课 注册功能分析,图片验证码视图设计 (课堂笔记)

    1,用户名     是否已注册 2,手机号 是否被注册 3,图形验证码 4,短信验证码, 5,验证成功后,向后台提交数据:用户名,密码,手机号,短信验证 要写这五个视图, 获取图形验证码,请求方式:g ...

  5. Vue常用V-标签

    1.v-once: 只绑定一次 2.v-html <div v-html='name'></div> //会渲染标签 var app = new Vue({ el:'#app' ...

  6. BZOJ1482 : [Balkan2017]Cats

    若猫和狗中至少有一个出现了$0$次,那么答案显然是$0$,否则若狮子出现了$0$次,那么显然无解. 那么现在至少有一个动物保持原地不同,其它动物恰好移动一次. 如果全部猫都不动而全部狗都动,那么可以贪 ...

  7. BZOJ4963 : String

    用SAM支持往末尾在线添加字符的功能. 设$f[i][j]$表示右端点为i的每个左端点的答案,那么当$i$变为$i+1$时,在SAM的parent链形成的树中会新增一个叶子$p$. 对于每个节点,维护 ...

  8. Linux之nginx反向代理三台web

    作业三:nginx反向代理三台web 实现基于轮询的方式调度三台web,并验证结果 实现基于权重的方式调度三台web,并验证结果 实现基于hash的方式调用三台web,并验证结果 [root@loca ...

  9. hihocoder1712 字符串排序(思维)

    https://hihocoder.com/problemset/problem/1712 感觉解法呼之欲出,却出不来.. 一个很好的思路是,根据新的顺序表,把给定的n组字符串换成旧表对应的字符,然后 ...

  10. CSS3-loading动画

    (二) 上次分享了四个CSS3的加载动画,今天继续(标题接上一次). 在线demo:http://liyunpei.xyz/loading.html   (持续更新) 请注意:代码中的关键帧动画有的用 ...