gpt4 book ai didi

c# - 如何在 .NET 中使用 RSA 和 SHA256 对文件进行签名?

转载 作者:IT王子 更新时间:2023-10-29 03:54:27 26 4
gpt4 key购买 nike

我的应用程序将获取一组文件并对其进行签名。 (我不是要签署程序集。)有一个 .p12 文件,我从中获取私钥。

这是我尝试使用的代码,但我收到了 System.Security.Cryptography.CryptographicException“指定的算法无效。”

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);

根据这个answer它无法完成(RSACryptoServiceProvider 不支持 SHA-256),但我希望它可能使用不同的库,如 Bouncy CaSTLe。

我是这方面的新手,我发现 Bouncy CaSTLe 非常令人困惑。我正在将 Java 应用程序移植到 C#,我必须使用相同类型的加密来签署文件,所以我只能使用 RSA + SHA256。

我如何使用 Bouncy CaSTLe、OpenSSL.NET、Security.Cryptography 或我没听说过的其他第 3 方库来做到这一点?我假设,如果可以用 Java 完成,那么也可以用 C# 完成。

更新:

这是我从 poupou 的回答中的链接得到的

X509Certificate2 cert = new X509Certificate2(KeyStoreFile, password");
RSACryptoServiceProvider rsacsp = (RSACryptoServiceProvider)cert.PrivateKey;
CspParameters cspParam = new CspParameters();
cspParam.KeyContainerName = rsacsp.CspKeyContainerInfo.KeyContainerName;
cspParam.KeyNumber = rsacsp.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2;
RSACryptoServiceProvider aescsp = new RSACryptoServiceProvider(cspParam);
aescsp.PersistKeyInCsp = false;
byte[] signed = aescsp.SignData(File.ReadAllBytes(file), "SHA256");
bool isValid = aescsp.VerifyData(File.ReadAllBytes(file), "SHA256", signed);


问题是我没有得到与使用原始工具相同的结果。据我所知,通过阅读代码可以看出,进行实际签名的 CryptoServiceProvider 没有使用 key 存储文件中的 PrivateKey。对吗?

最佳答案

RSA + SHA256 可以而且将会工作...

您后面的示例可能不会一直有效,它应该使用散列算法的 OID,而不是它的名称。根据您的第一个示例,这是通过调用 CryptoConfig.MapNameToOID(AlgorithmName) 获得的其中 AlgorithmName 是您提供的内容(即“SHA256”)。

首先您需要的是带有私钥的证书。我通常使用公钥文件 (.cer) 从 LocalMachine 或 CurrentUser 存储中读取我的私钥,然后枚举证书并匹配散列...

X509Certificate2 publicCert = new X509Certificate2(@"C:\mycertificate.cer");

//Fetch private key from the local machine store
X509Certificate2 privateCert = null;
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach( X509Certificate2 cert in store.Certificates)
{
if (cert.GetCertHashString() == publicCert.GetCertHashString())
privateCert = cert;
}

无论您如何到达那里,一旦您获得了带有私钥的证书,我们就需要重建它。由于证书创建私钥的方式,这可能是必需的,但我不确定为什么。无论如何,我们首先导出 key ,然后使用您喜欢的任何中间格式重新导入它,最简单的是 xml:

//Round-trip the key to XML and back, there might be a better way but this works
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
key.FromXmlString(privateCert.PrivateKey.ToXmlString(true));

一旦完成,我们现在可以按如下方式对一段数据进行签名:

//Create some data to sign
byte[] data = new byte[1024];

//Sign the data
byte[] sig = key.SignData(data, CryptoConfig.MapNameToOID("SHA256"));

最后,验证可以直接用证书的公钥完成,不需要像我们用私钥那样重构:

key = (RSACryptoServiceProvider)publicCert.PublicKey.Key;
if (!key.VerifyData(data, CryptoConfig.MapNameToOID("SHA256"), sig))
throw new CryptographicException();

关于c# - 如何在 .NET 中使用 RSA 和 SHA256 对文件进行签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7444586/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com