C#中如何使用预定义指数与模数实现RSA字符串加密并解决坏数据异常
错误原因
你代码存在两个核心问题导致抛出坏数据异常:
- 数值赋值搞反:你代码里
modulus变量存的是题目给出的指数值,exponent变量存的是题目给出的模数值,完全和要求的参数反过来了。 - 字节转换逻辑错误:
RSAParameters要求的Modulus和Exponent是大整数对应的大端序原始字节数组,不是数字字符串的ASCII编码结果,你直接用Encoding.ASCII.GetBytes处理大数字符串的逻辑完全不成立。你之前把指数缩短到4个字符能跑通纯粹是歪打正着,刚好生成的字节数组长度符合RSA组件对小指数的校验要求,逻辑本身是错的。
解决方法
用System.Numerics.BigInteger处理大整数到字节数组的转换即可,步骤如下:
- 引用
System.Numerics命名空间(.NET Core/.NET 5+自带,.NET Framework需要通过NuGet安装System.Numerics包) - 写辅助方法把十进制大整数字符串转成符合RSA要求的大端序无符号字节数组
- 修正参数赋值,不要搞混指数和模数
修正后的完整代码
using System; using System.Numerics; using System.Security.Cryptography; using System.Text; public class RsaEncryption { private RSAParameters rsaparam = new RSAParameters(); private RSACryptoServiceProvider csp; // 注意:这里修正了赋值,和题目给出的参数对应 public string modulusStr = "99656440840574176563305385521896948249485597887868788305755844436736" + "81373571688938415608140410885678541170145805757280770160982137713823" + "89714825959368173513133776394580030346373515296029247746151060318750" + "65736828376549082962569871367654360928995574432638495308492887000005" + "021125506027838956077501182295786099"; public string exponentStr = "11362144024378542149995530613390009998716430950387619937190061108597" + "56991949056217104428764418891953024519224435553542666457374543274095" + "09639333989384262385729949578624044207610948821627355876693570108394" + "89980856934670387451355246115777158531243784255520787524178833140187" + "0311503661882350734256428011446552231"; // 辅助方法:十进制大整数字符串转大端序无符号字节数组 private byte[] BigIntStringToBigEndianBytes(string bigIntStr) { BigInteger bigInt = BigInteger.Parse(bigIntStr); byte[] bytes = bigInt.ToByteArray(); // BigInteger默认返回小端序,且如果最高位是1会多一个0字节表示正数,这里要处理 Array.Reverse(bytes); if (bytes[0] == 0) { byte[] trimmed = new byte[bytes.Length - 1]; Array.Copy(bytes, 1, trimmed, 0, trimmed.Length); return trimmed; } return bytes; } public RsaEncryption() { rsaparam.Modulus = BigIntStringToBigEndianBytes(modulusStr); rsaparam.Exponent = BigIntStringToBigEndianBytes(exponentStr); } public string Encrypt(string plainText) { csp = new RSACryptoServiceProvider(); csp.ImportParameters(rsaparam); var data = Encoding.Unicode.GetBytes(plainText); // 注意:第二个参数false表示用PKCS#1 v1.5填充,对应你之前的写法 var cypher = csp.Encrypt(data, false); return Convert.ToBase64String(cypher); } }
额外注意
你给出的指数长度非常大,远超常规RSA用的3~4字节指数(比如常见的65537也就是0x010001),这种大指数会导致加密运算速度极慢,仅适合作业测试场景,生产环境不会这么使用。
内容的提问来源于stack exchange,提问作者Ozone Developer
相关产品推荐
相关产品推荐

