在签名和验证数据中为什么要有原始数据来验证?

In sign and verification data why should have original data to verification?

我正在阅读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);

举个例子,我们在服务端签了一个数据,然后发给客户端,客户端想知道是不是我发了那个数据,我为什么要发原始数据直到客户端可以验证呢?

有一些 post 以同样的方式做到了:

当传递 signedData 时,另一部分不知道 originalData 是什么,仅此而已。
要验证,您需要 signedData 和 [ originalData 和 public-key ]。

上面代码中的VerifySignedHash函数,调用了RSACryptoServiceProvider.VerifyData.


来自docs

Verifies that a digital signature is valid by determining the hash value in the signature using the provided public key and comparing it to the hash value of the provided data.

加密散列函数 hash(x) 具有某些理想的属性:

  1. One-way: hash(x) 给你 y。给定 x,很容易计算 y。但反过来,给定 y,找到 x 可能非常困难或不可能。
  2. Collisions:由于输入的大小(以位为单位)远大于散列大小(例如:我们可以计算千兆字节数据的 SHA-256),多个输入理论上可以产生相同的散列。虽然理论上是这样,但哈希算法旨在将实际设置中的冲突降至最低。
  3. 不可预测性:输入的微小变化会导致生成完全不同的哈希值。这有助于检测数据篡改(例如:将付款从 $100.00 更改为 $10000)

这些是使散列适用于加密签名和验证这些签名的一些属性。

why should we use original data for verification (paraphrased)

发送原始数据允许接收方独立重新计算哈希值,并比较发送方发送的哈希签名值,以确保接收到的数据与发送方发送的相同。