我有一个用 edcsa-sha384 签名的
XMLDocument
,开箱即用。NET SignedXml
不支持该算法,所以我遵循了这篇文章(https://www.scottbrady91.com/c-sharp) /ecdsa-xml-dotnet)并在程序开始时调用 AddAlgorithm
:
CryptoConfig.AddAlgorithm(typeof(Ecdsa384SignatureDescription),
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384");
在
AddAlgorithm
之前,SignedXml
能够 CheckSignature
很好地用于 rsa-sha256
,它能够遍历 XMLDocument 并执行签名检查,而不会引发任何错误...
在
AddAlgorithm
之后,它在 xml 文件的第二行抛出一个错误...有谁知道我还缺少什么来让 ECDsa-RSA-384 工作?
InvalidOperationException
> There is an error in the XML document.
> <MySpecialDoc xmlns='https://www.hello.com/world/1.0'> was not expected.
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)
XML 的开头如下:
<?xml version="1.0"?>
<MySpecialDoc xmlns='https://www.hello.com/world/1.0' id="9baedc57-c4ef-41f5-8bdf-33fb14af3f71">
...
如果您知道如何注册自定义算法的文章,请分享。谢谢!
好吧,我已经找到了错误的根本原因,它与我的方式无关
AddAlgorithm
,它实际上工作得很好。我看到的错误是由于我的 XmlDocument 中的命名空间不同所致。我生成了一些 C# 对象类,其中的命名空间是针对 1.1
进行编码的,而我正在阅读的 XML 是较旧的 1.0
!!!!!!
我花了很多时间研究和让 ECDsa 算法与它一起工作
SignedXml
,实际上没有太多关于这方面的信息,所以希望这个答案能够帮助其他人。
要将不支持的算法添加到
SignedXml
,您必须先创建一个SignatureDescription
类,然后通过SignedXml
注册CryptoConfig.AddAlgorithm
使用。
这是 ECDsa P-384 的
SignatureDescription
示例,在键入本文时已在 .NET 8 中进行了测试。 Ecdsa384SignatureDescription.cs
的代码(您可以将其包装在System.Security.Cryptography
命名空间中,但不确定如果 .NET 实际提供了实现,这是否会发生冲突):
using System.Security.Cryptography;
public class ECDsaCngSignatureFormatter : AsymmetricSignatureFormatter
{
private ECDsaCng? key;
public ECDsaCngSignatureFormatter(ECDsaCng key)
{
this.key = key;
}
public override void SetKey(AsymmetricAlgorithm key) => this.key = key as ECDsaCng;
public override void SetHashAlgorithm(string strName) { }
public override byte[] CreateSignature(byte[] rgbHash) => key!.SignHash(rgbHash);
}
public class ECDsaCngSignatureDeformatter : AsymmetricSignatureDeformatter
{
private ECDsaCng? key;
public ECDsaCngSignatureDeformatter(ECDsaCng key)
{
this.key = key;
}
public override void SetKey(AsymmetricAlgorithm key) => this.key = key as ECDsaCng;
public override void SetHashAlgorithm(string strName) { }
public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) => key!.VerifyHash(rgbHash, rgbSignature);
}
public class Ecdsa384SignatureDescription : SignatureDescription
{
public Ecdsa384SignatureDescription()
{
KeyAlgorithm = typeof(ECDsaCng).AssemblyQualifiedName;
}
public override HashAlgorithm CreateDigest() => SHA384.Create();
public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
if (!(key is ECDsaCng ecdsa) || ecdsa.KeySize != 384)
throw new InvalidOperationException("Requires EC key using P-384");
return new ECDsaCngSignatureFormatter(ecdsa);
}
public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
if (!(key is ECDsaCng ecdsa) || ecdsa.KeySize != 384)
throw new InvalidOperationException("Requires EC key using P-384");
return new ECDsaCngSignatureDeformatter(ecdsa);
}
}
创建该类后,您需要在程序中的某个位置注册它:
CryptoConfig.AddAlgorithm(typeof(Ecdsa384SignatureDescription),
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384");
您现在应该能够使用 ECDsa P-384 进行签名和验证签名。