我需要实现EBICS协议并签署HPB XML请求。
我的签名是在我的XML文件中正确生成的,但是当服务器验证它时,我得到以下回复,我不明白为什么:
身份验证签名无效
你能帮我解决我的问题吗?
这是我生成签名的代码:
方法:SignXml()
public static void SignXml()
{
CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = false;
xmlDoc.Load("hpbtest.xml");
RSACryptoServiceProvider Key = new RSACryptoServiceProvider();
X509Certificate2 Cert = new X509Certificate2("cert.pfx", "password", X509KeyStorageFlags.Exportable);
Key.FromXmlString(Cert.PrivateKey.ToXmlString(true));
// Create a SignedXml object.
PrefixedSignedXML signedXml = new PrefixedSignedXML(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "#xpointer(//*[@authenticate='true'])";
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
// Add an enveloped transformation to the reference.
XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
env.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Compute the signature.
signedXml.ComputeSignature("ds");
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml("ds");
// Append the element to the XML document.
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
xmlDoc.Save("hpbtest.xml");
}
Class PrefixedSignedXml
public class PrefixedSignedXML : SignedXml
{
XmlDocument xmlDocumentToSign;
public PrefixedSignedXML(XmlDocument document)
: base(document)
{
xmlDocumentToSign = document;
}
public PrefixedSignedXML(XmlElement element)
: base(element)
{ }
public PrefixedSignedXML()
: base()
{ }
public void ComputeSignature(string prefix)
{
this.BuildDigestedReferences();
AsymmetricAlgorithm signingKey = this.SigningKey;
if (signingKey == null)
{
throw new CryptographicException("Cryptography_Xml_LoadKeyFailed");
}
SignatureDescription description = CryptoConfig.CreateFromName(this.SignedInfo.SignatureMethod)as SignatureDescription;
if (description == null)
{
throw new CryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");
}
HashAlgorithm hash = description.CreateDigest();
if (hash == null)
{
throw new CryptographicException("Cryptography_Xml_CreateHashAlgorithmFailed");
}
this.GetC14NDigest(hash, prefix);
this.m_signature.SignatureValue = description.CreateFormatter(signingKey).CreateSignature(hash);
}
public XmlElement GetXml(string prefix)
{
XmlElement e = this.GetXml();
SetPrefix(prefix, e);
return e;
}
private void BuildDigestedReferences()
{
Type t = typeof(SignedXml);
MethodInfo m = t.GetMethod("BuildDigestedReferences", BindingFlags.NonPublic | BindingFlags.Instance);
m.Invoke(this, new object[] { });
}
private byte[] GetC14NDigest(HashAlgorithm hash, string prefix)
{
XmlDocument document = new XmlDocument();
document.PreserveWhitespace = false;//Aucune influence sur la signature
XmlElement e = this.SignedInfo.GetXml();
document.AppendChild(document.ImportNode(e, true));
Transform canonicalizationMethodObject = this.SignedInfo.CanonicalizationMethodObject;
SetPrefix(prefix, document.DocumentElement);
canonicalizationMethodObject.LoadInput(document);
return canonicalizationMethodObject.GetDigestedOutput(hash);
}
private void SetPrefix(String prefix, XmlNode node)
{
foreach (XmlNode n in node.ChildNodes)
SetPrefix(prefix, n);
node.Prefix = prefix;
}
public override XmlElement GetIdElement(XmlDocument document, string idValue)
{
XmlElement matchingElement = null;
try
{
matchingElement = base.GetIdElement(document, idValue);
}
catch (Exception idElementException)
{
Trace.TraceError(idElementException.ToString());
}
if (matchingElement == null)
{
// at this point, idValue = xpointer(//*[@authenticate='true'])
string customXPath = idValue.TrimEnd(')');
customXPath = customXPath.Substring(customXPath.IndexOf('(') + 1);
matchingElement = xmlDocumentToSign.SelectSingleNode(customXPath) as XmlElement;
}
return matchingElement;
}
}
Class RsaPkCs1Sha256SignatureDescription
public class RsaPkCs1Sha256SignatureDescription : SignatureDescription
{
public static void Register()
{
CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha256SignatureDescription),"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
}
public RsaPkCs1Sha256SignatureDescription()
{
KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
}
public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
var asymmetricSignatureDeformatter = (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
asymmetricSignatureDeformatter.SetKey(key);
asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256");
return asymmetricSignatureDeformatter;
}
public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
var asymmetricSignatureFormatter =
(AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
asymmetricSignatureFormatter.SetKey(key);
asymmetricSignatureFormatter.SetHashAlgorithm("SHA256");
return asymmetricSignatureFormatter;
}
}
最终签名结果
<?xml version="1.0" encoding="UTF-8"?>
<ebicsNoPubKeyDigestsRequest xmlns="http://www.ebics.org/H003" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ebics.org/H003 http://www.ebics.org/H003/ebics_keymgmt_request.xsd" Version="H003" Revision="1">
<header authenticate="true">
<static>
<HostID>EBIXQUAL</HostID>
<Nonce>234AB2340FD2C23035764578FF3092D3</Nonce>
<Timestamp>2015-12-04T10:07:27.123Z</Timestamp>
<PartnerID>AD598</PartnerID>
<UserID>EF056</UserID>
<OrderDetails>
<OrderType>HPB</OrderType>
<OrderAttribute>DZHNN</OrderAttribute>
</OrderDetails>
<SecurityMedium>0000</SecurityMedium>
</static>
<mutable />
</header>
<AuthSignature>
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<ds:Reference URI="#xpointer(//*[@authenticate='true'])">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>2glaCqpZf0XMkqB+twtAsJtKo9MWg60FaMBwJ91xNGQ=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>FISRuQ0WTanCkvhc9/m/9OIHCd+hfPl4WjqVlhPQx5AoBe/yNFBQoXwC+d3os7kaxDvZghIosLzcIc/69M5YUAn/njlWAzYL+pqtXXy3Ea9SxMqeb3BwPVLMfkgY2TUo7QIlnv+omUPRq0PzDi50iZFv4sh+TBdWIEs29JJET/48MP+d67MqpdN5NRtM3C2QDWpRhe4erKoRCJC1OW+DkIHdKZ4lqJpKp1cdcooCRGXod9+6usxbfD8LU0Ow7wTJl2crUya9Elx+gxGUogo7bBrRnRpWM/5ih12KcoXQ/mKRpwKCbk+vYRF9E66/2SVjRZSkmFm1xeENRiZJ5tJDRg==</ds:SignatureValue>
</AuthSignature>
<body />
</ebicsNoPubKeyDigestsRequest>
我真的尝试了一切,但我不明白为什么它不起作用:(
提前谢谢!
托马斯