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);
}
我是一名优秀的程序员,十分优秀!