我的项目需要与支付网关集成。该项目内置于 .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;
}