数字签名:加密哈希与签署哈希?

时间:2016-12-10 04:03:44

标签: c# encryption cryptography certificate

我试图实施SHA256-RSA数字签名,并且我对C#中的术语和实现感到困惑。

AFAIK,"签署文件"是生成文件的哈希值,然后加密该哈希值。我也听过这句话"签署哈希"。这是一回事吗?或者这是哈希哈希,然后加密哈希'?

以下是有问题的代码:

public void SignatureTest(byte[] data, X509Certificate2 cert)
{
    var sha256 = new SHA256CryptoServiceProvider();
    var rsa = (RSACryptoServiceProvider)cert.PrivateKey;

    var hashOfData = sha256.ComputeHash(data);

    var encryptedHash = rsa.Encrypt(hashOfData, false);
    var encryptedHashOAEP = rsa.Encrypt(hashOfData, true);            
    var signedHash = rsa.SignHash(hashOfData, "SHA256");

    //Shouldn't one of these be true?
    var false1 = CompareAsBase64Str(encryptedHash, signedHash);
    var false2 = CompareAsBase64Str(encryptedHashOAEP, signedHash);

    //This is the one that actually matches
    var true1 = CompareAsBase64Str(signedHash, rsa.SignData(data, sha256));
}

public bool CompareAsBase64Str(byte[] b1, byte[] b2)
{
    return (Convert.ToBase64String(b1) == Convert.ToBase64String(b2));
}

这是MSDN在RSACryptoServiceProvider上所说的内容:

SignHash()使用私钥计算指定哈希值的签名

使用RSA算法加密()加密数据

不应该使用SignHash(哈希)和加密(哈希)相同吗?

2 个答案:

答案 0 :(得分:5)

您需要分开关注点,这有助于您理解术语。

任意组合的任意blob都可以hash和/或encrypt组合。 Hash表示:使用加密算法生成不可逆的值(即,简单地通过了解您无法重构原始数据的算法和哈希)和一致性(即,给定相同的数据和算法,产生的哈希值总是相同的。)

Encrypt表示:使用加密算法用给定密钥加密数据(完全或在块中)(密钥可以是对称的或非对称的)。

Sign表示:Hash数据和Encrypt具有给定键的哈希值。然后,给定对(用于非对称)或相同(用于对称)密钥,消费者可以验证:

  1. 哈希匹配,这意味着数据在传输过程中未被更改
  2. hash确实来自至少具有配对密钥(用于非对称)或相同密钥(用于对称)的源

答案 1 :(得分:5)

The answer given by zaitsman是对与您的问题相关的主题的一个很好的解释,我认为应该是接受的答案,但只是为了帮助将其与您的特定问题联系起来,为什么加密哈希不会给您带来与签名哈希(代码中的rsa.SignHash(hashOfData, "SHA256"))相同的结果:

签署哈希不会加密哈希数据 - 它还会加密用于生成哈希的哈希算法的名称(或某些标识符)。如果没有这个,接收器就不会知道在计算他们自己的哈希(被发送的消息)时要使用什么算法来与他们刚刚解密的哈希进行比较,以便验证消息的真实性(当然,这是整点)。

当您自己加密哈希值(使用rsa.Encrypt(hashOfData, false)rsa.Encrypt(hashOfData, true))时,您只加密了哈希数据,而不是哈希数据的组合 算法标识符(代码中为"SHA256")。换句话说,您加密了不同的数据,因此您获得了不同(加密)的结果

SignHash调用的返回值匹配 rsa.SignData(data, sha256)返回的值的原因是后一种方法做同样的事情,除了它进行散列和散列签名作为一个操作,因此如果除了签名之外不需要将哈希用于任何目的,则不必将哈希计算为单独的步骤。

来自MSDN上的RSACryptoServiceProvider.SignData Method

  

计算指定数据的哈希值并对其进行签名。


另请参阅:Why does SignHash need to know what hash algorithm was used?