如何在 C# .NET 中正确为 ECDsa 进行 CryptoConfig.AddAlgorithm?

问题描述 投票:0回答:1

我有一个用 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">
...

如果您知道如何注册自定义算法的文章,请分享。谢谢!

c# .net cryptography ecdsa xml-signature
1个回答
0
投票

好吧,我已经找到了错误的根本原因,它与我的方式无关

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 进行签名和验证签名。

© www.soinside.com 2019 - 2024. All rights reserved.