c# - 为什么我的 RSA 签名实施适用于某些消息,但不适用于其他消息?
问题描述
我试图在 C# 中实现一个简单的 RSA 签名算法,只使用 BigInteger,没有内置的加密工具。为了签署一条消息,我用私钥对其进行加密,为了验证它,我用公钥对其进行解密。在下面的代码中,我注意到一个非常奇怪的行为。对于某些输入字符串(例如“Test”),它成功验证了签名,但对于其他字符串(例如“Test1”),它失败了。
我注意到的是,只有当m
变量(消息的哈希)为负数时它才会失败,这会导致解密的ver
变量变成一个非常大的数字并且代码打印“错误签名”。
// Generating RSA keys
var random = new Random();
var p = new BigInteger(256, 100, random);
var q = new BigInteger(256, 100, random);
var n = p.Multiply(q);
var phi = p.Subtract(BigInteger.One).Multiply(q.Subtract(BigInteger.One));
var e = new BigInteger("65537");
var d = e.ModInverse(phi);
// Preparing the message
var messageHash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("Test"));
var m = new BigInteger(messageHash);
// Signing the message
var signature = m.ModPow(d, n);
// Verifying the message
var ver = signature.ModPow(e, n);
Console.Out.WriteLine(m);
Console.Out.WriteLine(ver);
if(ver.Equals(m))
Console.Out.WriteLine("Valid Signature");
else
Console.Out.WriteLine("Wrong Signature");
我使用 BouncyCastle 作为BigInteger
类型。
消息“测试”的示例输出:
16928957987407306249184430693954511195
16928957987407306249184430693954511195
Valid Signature
消息“Test1”的示例输出:
-40249184872970767997805928798048797124
10061048024793920770364189111057222210443355984675629704584018449091407182950576678391694061743052292040531884029654111183675927763342349593675935744009443
Wrong Signature
我相信错误是在签名过程中的某个地方,而不是在验证中。也许我不应该尝试加密负数?如果哈希是负数怎么办?如何修复此代码,使其在任何输入字符串上都能可靠运行?
解决方案
@Topaco 帮助我解决了我的问题。
对于消息 m 和模数 n,RSA 算法需要 0 <= m < n,这里。为了防止负数, var m = new BigInteger(1, messageHash); 可以使用,它创建相应的无符号值而不是有符号值
推荐阅读
- reactjs - 如何在 React 中将经典组件转换为功能组件
- css - 在@for scss中将变量递增为背景后显示错误
- excel - 在 Excel (VBA) 中使用 Google API 计算地址之间的距离
- sql - 条件聚合中的sql更新语句
- python - Tkinter:对全局变量所做的更改不会保留
- excel - 如何将数据从用户窗体插入到具有特定值的特定行
- python - 在 conda envvironment 中使用“black filename.py”时,Python Black 包不起作用
- javascript - Unable to get data from different origin/host JQuery Nodejs-Express
- react-native - 在 Blur 上销毁 React Native 组件
- php - 会话未正确结束