简体   繁体   English

如何在 .net ( C# ) 中使用标准 ISO20022 创建数字签名的 Xml 消息?

[英]How to create digitally signed Xml Message using standard ISO20022 in .net ( C# )?

My project needs integration with payment gateway.我的项目需要与支付网关集成。 The project is built in .net ( c# ) To integrate the gateway i need to sign XML message digitally following ISO 20022 standard.该项目是在 .net ( c# ) 中构建的,为了集成网关,我需要按照 ISO 20022 标准对 XML 消息进行数字签名。 I am using dot net library SignedXml of System.Security.Cryptography The sample format and my code is shown below :我正在使用 System.Security.Cryptography 的点网库 SignedXml 示例格式和我的代码如下所示:

Sample Code:示例代码:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
        <ds:Reference URI="">
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <ds:DigestValue>eoXljsKRVEUPMMqrqjdtHyIUD4GyjeIsGPx8vVLey9g=</ds:DigestValue>
        </ds:Reference>
        <ds:Reference URI="#49e752ba-8e80-4be5-8538-67866c2e1dd9">
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <ds:DigestValue>n4pKHz5MvOPK7uDcdyFlxZrEz3kgtq6t56HcEdDmeyA=</ds:DigestValue>
        </ds:Reference>
        <ds:Reference>
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <ds:DigestValue>ZH7NiLE0HlL8nIChNnauUXYugxZlX6rgUI2YMSrzSyE=</ds:DigestValue>
        </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>
        KN6PPWZQ/C8AHexw+nqfX375S3rm4CyqjWxfzWcHGEpAfxE3j7RKArxq0Xx5ofnILJ0g5LlxKgNS
        YDJJ+HB/cc6S4LzWFFRbwL9U9fC8ZXNWk/Sf+4SSK/t/Aaz2TqYUDrpd4Q+qq8e+EMryI2sULRtC
        FxvBU/BRAAnnZhLBDQX3crSHU3ynaOSeicFbAaX1LuwCsKppqSZSFcq3MHgIQ4PBFFRlLtXVuQms
        I8ZYpSe2ZsxSlCwaSdNMXpQDunhbTQE464691W+kyBczVz37/jsCKy8q2AM5JA4sabHgMpO5NxsZ
        eK00sNKG+guRSTuMsZpdVaMZPjNI3aMxB+JHHw==
    </ds:SignatureValue>
    <ds:KeyInfo Id="49e752ba-8e80-4be5-8538-67866c2e1dd9">
        <ds:X509Data>
            <ds:X509SKI>
                udATCnB3DNmvJuBuZCU/NCOAxU0=
            </ds:X509SKI>
        </ds:X509Data>
    </ds:KeyInfo>
</ds:Signature>

My code : When i try to run this adding reference with Unique Identifier,我的代码:当我尝试使用唯一标识符运行此添加引用时,

 Reference referenceKeyInfo = new Reference();
 referenceKeyInfo.Uri = "#"+keyInfo.Id;

I receive response as : Malformed reference element我收到的回复是: Malformed reference element

Also if someone can help me in how to create Reference without URI attribute?另外,如果有人可以帮助我如何创建没有 URI 属性的引用?

        {
            //Access certificate
            X509Certificate2 cert = null;

            X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            certStore.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certCollection = certStore.Certificates.Find(
                                       X509FindType.FindByThumbprint,
                                       "MY CERTIFICATE THUMBPRINT HERE",
                                       false);
            cert = certCollection[0];



            XmlDocument doc = new XmlDocument();
            XmlSerializer payloadserializer = new XmlSerializer(typeof(RequestPayload));
            var writer = new StringWriter();
            //serilize object to xml
            payloadserializer.Serialize(writer, requestPayload);
            string xml = writer.ToString();
            //load xml into XmlDocument
            doc.LoadXml(xml);

            //create object for xml signature and assign certificate private key to signature signing key
            SignedXml signedXml = new SignedXml(doc);
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            /////Signature value
            signedXml.SigningKey = cert.PrivateKey;

            //create key info node of signature
            KeyInfo keyInfo = new KeyInfo();
            keyInfo.Id = Guid.NewGuid().ToString();//Id is uniq ID
            //// Reference Header element

            //create reference element of xml, for header and assign uri(default uri, uri="")
            Reference referenceHeader = new Reference();
            referenceHeader.Uri = "#header";
            referenceHeader.LoadXml(header);
            //create transofrm node for signature
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
            //done canonicalisation on transform and allows a signer to create a digest
            XmlDsigExcC14NTransform headerC14n = new XmlDsigExcC14NTransform();
            //add transform to reference node before digest algorithm
            referenceHeader.AddTransform(env);
            referenceHeader.AddTransform(headerC14n);
            signedXml.AddReference(referenceHeader);

            //create reference element of xml, for KeyInfo and uri with #document, which will be replace by uniqId
            Reference referenceKeyInfo = new Reference();
            referenceKeyInfo.Uri = "#"+keyInfo.Id;
            XmlDsigExcC14NTransform keyInfoC14n = new XmlDsigExcC14NTransform();
            referenceKeyInfo.AddTransform(keyInfoC14n);
            signedXml.AddReference(referenceKeyInfo);

            ////reference document element
            //create reference element of xml, for document and uri is absent            
            Reference referenceDocument = new Reference();           
            //done canonicalisation on transform and allows a signer to create a digest
            XmlDsigExcC14NTransform documentC14n = new XmlDsigExcC14NTransform();
            //add transform to reference node before digest algorithm
            referenceDocument.AddTransform(documentC14n);
            signedXml.AddReference(referenceDocument);



            ////KeyInfo element of signature
            // create KeyInfo element then create X509 element and add subject key id
            KeyInfoX509Data keyInfoData = new KeyInfoX509Data();
            keyInfoData.AddSubjectKeyId("MY CERTIFICATE SUBJECT KEY ID HERE");
            keyInfo.AddClause(keyInfoData);
            signedXml.KeyInfo = keyInfo;

            // Compute the signature.
            signedXml.ComputeSignature();

            XmlElement xmlDigitalSignature = signedXml.GetXml();
            SetPrefix("ds", xmlDigitalSignature);
            string signatureXml = xmlDigitalSignature.OuterXml.ToString();
            requestPayload.AppHdr.Sgntr = signatureXml;
        }

The default implementation of SignedXml cannot be used with an id that also has a namespace. SignedXml的默认实现不能与同样具有命名空间的 id 一起使用。

It seems that the only way to deal with this is to create a custom subclass of SignedXml and override the GetIdElement method as recommended by this answer https://stackoverflow.com/a/6467877/536546似乎解决此问题的唯一方法是创建SignedXml的自定义子类并按照此答案https://stackoverflow.com/a/6467877/536546 的建议覆盖GetIdElement方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 XML使用c#从xsd反序列化iso 20022 pain.001.001.03 - XML deserialize iso 20022 pain.001.001.03 from xsd using c# 如何在 C# 中生成数字签名的 XML 文档的 XML 的 .sig? - How to generate .sig of XML of digitally signed XML document in C#? 如何在C#中验证经过数字签名的XML文档? - How do I validate digitally signed XML documents in C#? 是否可以使用open ssl创建经过数字签名的xml? - Is it possible to create digitally signed xml using open ssl? c# camt54 (iso 20022) 中的日期时间反序列化问题 - c# Datetime deserialization problem in camt54 (iso 20022) 如何使用C#获取经过数字签名的Outlook .msg文件的正文文本 - How to get the Body text of the digitally signed outlook .msg file using C# 如何验证数字签名的XML文件? - How to verify Digitally Signed XML File? 我如何使用BouncyCastle密码库(C#版本)的ArmoredOutputStream创建带ARMi签名的OpenPGP消息 - How do I create an ascii-armored signed OpenPGP message using ArmoredOutputStream of the BouncyCastle crypto library (C# version) 如何使用iTextSharp密码保护数字签名的pdf? - how to password protect the digitally signed pdf using iTextSharp? 如何使用PGP机制对文本文件进行数字签名 - How to digitally signed a text file using PGP mechanism
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM