RSACryptoServiceProvider 中存在一个奇怪的设计问题:
虽然可以使用 RSACryptoServiceProvider.SignData 对非常大的文件进行签名:
public byte[] SignData(
Stream inputStream,
Object halg
)
,如果不将文件完全读入内存缓冲区,则无法实际验证大文件。 唯一可用method是:
public bool VerifyData(
byte[] buffer,
Object halg,
byte[] signature
)
强制调用者将整个文件读入内存(可能在调用代码中产生 OutOfMemoryException)。
我研究了扩展 RSACryptoServiceProvider,因为在内部,VerifyData 方法可以很容易地重载以支持流。然而,该类是密封的,并且该方法在内部使用了一堆我无法访问的内部方法。
有人遇到过这个问题吗?有什么简单的方法可以解决这个问题吗?
顺便说一句 - 对于 MS,修复将是 6 行复制和粘贴,并更改单个 var 类型...
最佳答案
这段代码可以解决问题:
public byte[] SignData(RSACryptoServiceProvider rsaEncryptor, Stream stream, Object halg)
{
HashAlgorithm hash = (HashAlgorithm) CryptoConfig.CreateFromName((string) halg); /*Utils.ObjToHashAlgorithm(halg)*/
byte[] hashVal = hash.ComputeHash(stream);
return rsaEncryptor.SignHash(hashVal, (string) halg);
}
public bool VerifyData(RSACryptoServiceProvider rsaEncryptor, Stream stream, Object halg, byte[] signature)
{
HashAlgorithm hash = (HashAlgorithm) CryptoConfig.CreateFromName((string) halg); /*Utils.ObjToHashAlgorithm(halg)*/
byte[] hashVal = hash.ComputeHash(stream);
return rsaEncryptor.VerifyHash(hashVal, (string) halg, signature);
}
调用它是通过以下方式完成的:
byte[] signature = SignData(rsa2, stream, "SHA256");
//here we write the signature to a file
和
if (VerifyData(rsaEncryptor, stream, "SHA256", File.ReadAllBytes(signatureFilePath)))
{
Console.WriteLine("Verification completed successfully for file {0}", filePath);
return true;
}
else
{
throw new CryptographicException("verification failed for file {0}", filePath);
}
关于c# - RSACryptoServiceProvider.VerifyData(stream) 验证大文件 : overcoming assymentric class design,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22748006/