问题描述
我正在读取this article,其中有两个字节数组,一个用于带符号数据,一个用于原始数据。
byte[] originalData = ByteConverter.GetBytes(dataString);
byte[] signedData;
我们对数据进行了签名,这部分还可以,但是我不明白为什么要使用原始数据?
// Hash and sign the data.
signedData = HashAndSignBytes(originalData,Key);
// Verify the data and display the result to the
// console.
VerifySignedHash(originalData,signedData,Key);
例如,我们在服务器中签名数据并将其发送给客户端,客户端希望找到我是否发送了该数据,为什么我应该发送原始数据,直到客户端可以验证它?
有一些帖子也以相同的方式完成了
- Signing and verifying signatures with RSA C#
- C# Signing and verifying signatures with RSA. Encoding issue
解决方法
通过signedData
时,另一部分不知道originalData
是什么,仅此而已。
要进行验证,既需要signedData
,也需要[originalData
和公钥]。
上面提到的代码中的VerifySignedHash
函数调用RSACryptoServiceProvider.VerifyData
。
来自docs:
,通过使用提供的公钥确定签名中的哈希值并将其与提供的数据的哈希值进行比较,验证数字签名是否有效。
密码哈希函数hash(x)具有某些理想的属性:
- 单向:哈希(x)给您y。给定x,很容易计算y。但是相反,给定y,找到x可能非常困难或不可能。
- 冲突:由于输入的大小(以位为单位)远大于哈希大小(例如:我们可以计算千兆字节的SHA-256数据),因此从理论上讲,多个输入可以产生相同的哈希。尽管从理论上讲是这样,但哈希算法的设计目的是在实际设置中将冲突降至最低。
- 不可预测性:输入中的微小变化会导致生成完全不同的哈希。这有助于检测数据篡改(例如:将付款从$ 100.00更改为$ 10000)
这些是使哈希适用于加密签名和验证这些签名的一些属性。
我们为什么要使用原始数据进行验证(释义)
发送原始数据可以使收件人独立地重新计算哈希值,并比较发送方发送的哈希签名值,以确保接收到的数据与发送方发送的数据相同。