![](/img/trans.png)
[英]XML deserialize iso 20022 pain.001.001.03 from xsd using c#
[英]How to create digitally signed Xml Message using standard ISO20022 in .net ( C# )?
我的項目需要與支付網關集成。 該項目是在 .net ( c# ) 中構建的,為了集成網關,我需要按照 ISO 20022 標准對 XML 消息進行數字簽名。 我正在使用 System.Security.Cryptography 的點網庫 SignedXml 示例格式和我的代碼如下所示:
示例代碼:
<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>
我的代碼:當我嘗試使用唯一標識符運行此添加引用時,
Reference referenceKeyInfo = new Reference();
referenceKeyInfo.Uri = "#"+keyInfo.Id;
我收到的回復是: Malformed reference element
另外,如果有人可以幫助我如何創建沒有 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;
}
SignedXml
的默認實現不能與同樣具有命名空間的 id 一起使用。
似乎解決此問題的唯一方法是創建SignedXml
的自定義子類並按照此答案https://stackoverflow.com/a/6467877/536546 的建議覆蓋GetIdElement
方法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.