.Net: SignedXml - Подписание xml с помощью алгоритма преобразования exc-c14n

Я пытаюсь подписать Xml (на самом деле SOAP xml) в C# с помощью класса SignedXml, этап подписания проходит успешно, но когда я пытаюсь проверить подпись, она говорит мне, что она недействительна. Единственное изменение, которое я сделал из примера в MSDN, это то, что я использовал XmlDsigExcC14NTransform вместо transform XmlDsigEnvelopedSignatureTransform. Если я использую XmlDsigEnvelopedSignatureTransform, я получу действительную подпись.

Вот мой код подписи:

 private static XmlDocument SignXml(XmlDocument doc)
             {
                 SignedXml signedXml = new SignedXml(doc);
                 signedXml.SigningKey = Certificate.PrivateKey;

                 Reference reference = new Reference();
                 reference.Uri = "";

                 XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
                 //XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();

                 reference.AddTransform(env);

                 signedXml.AddReference(reference);
                 signedXml.ComputeSignature();

                 XmlElement signature = signedXml.GetXml();
                 doc.DocumentElement.AppendChild(signature);
                 doc.Save(SignedXmlPath);
                 return doc;
             }

Приведенный выше код даст мне действительную подпись, но если я использую

XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();

вместо

XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

Я получу неверную подпись.

Вот мой проверочный код:

private static bool Verify(XmlDocument doc)
        {
            SignedXml signedDoc = new SignedXml(doc);
            XmlNodeList nodeList = doc.GetElementsByTagName(Constants.SignatureElement);

            signedDoc.LoadXml((XmlElement)nodeList[0]);
            return signedDoc.CheckSignature((RSA)Certificate.PublicKey.Key);
        }

Может кто-нибудь сказать мне, как я могу подписать с помощью алгоритма преобразования http://www.w3.org/2001/10/xml-exc-c14n#

Заранее спасибо.

1 ответ

Решение

Тебе понадобится XmlDsigEnvelopedSignatureTransform в вашем случае, потому что вы добавляете подпись внутри элемента, который вы подписываете.

XmlDsigEnvelopedSignatureTransform скажет SignedXml класс для удаления подписи из самого узла подписи перед проверкой его действительности. Это необходимо, потому что вы добавили этот элемент после расчета подписи.

Вы можете добавить более одного преобразования, вызвав AddTransform опять вот так:

XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
XmlDsigExcC14NTransform c14n = new XmlDsigExcC14NTransform();

reference.AddTransform(env);
reference.AddTransform(c14n);

Однако, я думаю, что вы на самом деле хотите сделать вместо моего примера выше, это установить CanonicalizationMethod до cnn:

signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
 - or - 
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
Другие вопросы по тегам