5

OpenSSL 以及大多数其他 DSA 实现以 ASN.1 格式输出签名。因此,由于 ASN.1 结构标头,40 字节签名(两个 20 字节整数)变为 46 字节。(有关详细信息,请参阅此论坛帖子。)

我的问题是,如何在 C# 中处理这种格式?(或其他地方,就此而言)

我花了一段时间试图使用 .NET 包来处理它System.Security.Crypto,但放弃了(真的很令人沮丧,因为它显然有解析 ASN.1 的内部代码,因为它可以读取 DER 格式,但是你没有办法使用它——但我离题了……

然后,我开始使用 BouncyCastle C# 库。我可以把它变成一个Asn1Object,如果我在调试时展开它,我会看到它包含一个DerSequence带有两个整数的 a,但是我如何把它们拉出来(最好BigIntegers是这样我可以把它们喂给DSA.VerifySignature?)

代码示例:

Byte[] msgText = ReadFile("test_msg.txt");
Byte[] msgSigRaw = ReadFile("test_sig_1.bin");  // reads binary ASN.1 sig using FileStream
Asn1Object sigASN = Asn1Object.FromByteArray(msgSigRaw);  // parses into Asn1Object
...
X509Certificate implCert = ReadCertificate("pubcert_dsa.cer");  // cert in DER format
DsaSigner DSA = new DsaSigner();
DSA.Init(false, implCert.GetPublicKey());
...
BigInteger sigIntR, sigIntS;
... //TODO: how to get signature from sigASN into sigIntR, sigIntS?
Boolean validSig = DSA.VerifySignature(msgText, sigIntR, sigIntS);  // my goal
4

2 回答 2

4

看看这篇 CodeProject 文章: http: //www.codeproject.com/KB/security/CryptoInteropSign.aspx

它包含将 DSA 签名转换为 C# 中预期的 P1363 格式的代码。

于 2009-12-02T11:19:21.637 回答
2

如何在 BouncyCastle C# 中验证 DSA 签名的一些示例代码:

ISigner sig = SignerUtilities.GetSigner("SHA1withDSA");
sig.Init(false, implCert.GetPublicKey());
sig.BlockUpdate(msgText, 0, msgText.Length);
bool valid = sig.VerifySignature(msgSigRaw);

请注意,此签名者将为您处理 ASN.1 和消息摘要的计算(我假设这里使用了 SHA-1)。

如果您仍然真的想知道 {r,s} 值与 ASN.1 之间的转换是如何发生的,请查看 DsaDigestSigner 的源代码。在内部,它执行适当的 ASN.1 编码/解码,然后使用 DsaSigner 类进行低级 sig 操作。

于 2010-02-02T12:45:23.543 回答