如何在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编码的签名中检索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解析器真的不是一个好选择,容易出现错误,必须有一种正确的方法来完成这个任务。