[英]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.