如何在 C# 中验证 DSA 签名?
鉴于:
- 消息文本,
- 签名摘要(通常为 ASN.1 DER 格式),
- 公钥(采用签名的 X.509 证书、PEM 或 DER 格式)
我尝试了多种方法,但都没有成功:
OpenSSL.NET:库的各种奇怪错误;我有一个与作者在 SourceForge 上运行的开放线程,但还没有解决这个问题。
Microsoft .NET API:无法解压缩 DER 签名进行比较。DSA 签名是 40 字节(两个 20 字节整数),但呈现为两个整数的 DER 编码序列,因此总长度可以在 46 到 48 字节之间(请参阅这篇文章以获得快速概述。)而 . NET 包含解析 ASN.1/DER 的代码(因为它可以读取 DER 格式的证书),它被深埋,无法访问它,因此您可以正确地从 ASN.1/DER 编码的 sig 中检索 40 个字节. 这个问题让我想到了下一个选择......
BouncyCastle:通过使用这些
Org.BouncyCastle.Asn1
函数,我可以解析 ASN.1 签名并将其拉入它的组件 R 和 S 整数值中。但是当我将这些传递给签名验证例程时,它失败了,没有给出任何解释。我不确定我是否做错了什么,因为 C# API完全没有文档,Java 版本几乎没有文档(但我找不到示例或 HOWTO 信息。)
我已经把自己扔在这个问题上大约一个星期了。我知道以前一定有人做过,但我还没有找到任何完整/有效的例子。
我这里有三个 C# 项目,每个项目都完成了 95%,但有一个导致它失败的关键缺陷。任何工作示例代码将不胜感激。
编辑:这是我正在尝试验证的签名示例,已转换为 Base64 和 ASCII 十六进制以使其可发布。这个特定的是 47 字节,但正确的解析器仍然必须接受它,阅读 DER 规范以获取更多信息(如果 MSB 为 1,BER/DER 添加前导 00 以确认符号)
Base64: MC0CFQCUgq2DEHWzp3O4nOdo38mDu8mStwIUadZmbin7BvXxpeoJh7dhquD2CTM=
ASCII Hex: 302d0215009482ad831075b3a773b89ce768dfc983bbc992b7021469d6666e29fb06f5f1a5ea0987b761aae0f60933
结构符合 DER 规范;它解析如下:
30 2d: sequence, length 45 (may vary from 44 to 46)
02 15: integer, length 21 (first byte is 00 to confirm sign)
009482ad831075b3a773b89ce768dfc983bbc992b7
02 14: integer, length 20 (leading 00 not necessary for this one)
69d6666e29fb06f5f1a5ea0987b761aae0f60933
编写我自己的 DER 解析器真的不是一种选择,错误的空间太大,必须有一种方法来正确地做到这一点。