我正在尝试实现the 256-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(散列)和Encrypt(散列)不应该相同吗?
发布于 2016-12-10 04:52:38
扎伊茨曼的回答很好地解释了与您的问题相关的主题,我认为这应该是公认的答案,但只是为了帮助将其与您的具体问题联系起来,即为什么加密哈希不能给出与签名哈希(代码中的rsa.SignHash(hashOfData, "SHA256") )相同的结果:
签名哈希不只是加密哈希数据--它还加密用于生成散列的散列算法的名称(或某些标识符)。否则,接收方将不知道在计算自己的散列(正在发送的消息)时使用什么算法来与他们刚刚解密的算法进行比较,以验证消息的真实性(当然,这就是关键所在)。
当您自己加密哈希时(使用rsa.Encrypt(hashOfData, false)和rsa.Encrypt(hashOfData, true)),您只加密哈希数据,而不加密哈希数据和算法标识符(代码中的"SHA256")的组合。换句话说,您加密了不同的数据,因此得到了不同的(加密)结果。
该SignHash调用的返回值与rsa.SignData(data, sha256)返回的值匹配的原因是,后一种方法执行相同的操作,但它将散列和哈希签名作为一个操作执行,因此,如果除了签名之外,不需要将哈希作为单独的步骤计算,则不必计算它。
来自MSDN上的RSACryptoServiceProvider.SignData法:
计算指定数据的哈希值并对其签名。
发布于 2016-12-10 04:12:20
您需要分离关注点,这将帮助您理解术语。
任何任意的数据块都可以在任何组合中被hash编辑和/或encrypt编辑。Hash的意思是:使用加密算法生成一个不可逆转的值(也就是说,仅仅通过知道算法和哈希您无法重构原始数据)和一致性(即,给定相同的数据和算法,产生的哈希值总是相同的)。
Encrypt的意思是:使用密码算法用给定的密钥(密钥可以是对称的或不对称的)加密数据(完全或块)。
Sign的意思是:Hash数据,并使用给定的键对哈希进行Encrypt。然后,给定对(非对称)或相同(对称)密钥,使用者可以验证:
https://stackoverflow.com/questions/41072042
复制相似问题