如何在.net(C#)中使用标准ISO20022创建经过数字签名的Xml消息? [英] How to create digitally signed Xml Message using standard ISO20022 in .net ( C# )?

查看:71
本文介绍了如何在.net(C#)中使用标准ISO20022创建经过数字签名的Xml消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目需要与支付网关集成.该项目是在.net(c#)中构建的为了集成网关,我需要按照ISO 20022标准对XML消息进行数字签名.我正在使用System.Security.Cryptography的点网库SignedXml示例格式和我的代码如下所示:

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. I am using dot net library SignedXml of System.Security.Cryptography The sample format and my code is shown below :

示例代码:

<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;

我收到以下答复:参考元素格式错误

还能有人帮助我如何创建不带URI属性的参考吗?

Also if someone can help me in how to create Reference without URI attribute?

        {
            //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;
        }

推荐答案

SignedXml 的默认实现不能与也具有命名空间的id一起使用.

The default implementation of SignedXml cannot be used with an id that also has a namespace.

看来,解决此问题的唯一方法是创建 SignedXml 的自定义子类,并按照此答案https://stackoverflow.com/a/6467877/536546

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

这篇关于如何在.net(C#)中使用标准ISO20022创建经过数字签名的Xml消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆