我一直在努力使.NET中的XMLDSIG支持正常运行,更具体地说是SignedXml类.我正在实施第三方服务,他们最近才开始要求所有消息都必须经过数字签名......
我的问题是,我似乎无法生成有效的签名.第三方服务和我找到的在线签名验证器都将签名报告为无效.验证服务(http://www.aleksey.com/xmlsec/xmldsig-verifier.html)报告摘要和数据之间存在不匹配,到目前为止我还无法弄清楚我在做什么错误.
这是相关的代码 - 希望有人能够发现我的错误;
public static XDocument SignDocument(XDocument originalDocument, X509Certificate2 certificate)
{
var document = new XmlDocument();
document.LoadXml(originalDocument.ToString(SaveOptions.DisableFormatting));
if (document.DocumentElement == null)
throw new InvalidOperationException("Invalid XML document; no root element found.");
var signedDocument = new SignedXml(document);
Reference signatureReference = GetSignatureReference();
KeyInfo certificateKeyInfo = GetCertificateKeyInfo(certificate);
var dataObject = new DataObject("", "text/xml", "utf-8", document.DocumentElement);
signedDocument.AddReference(signatureReference);
signedDocument.AddObject(dataObject);
signedDocument.SigningKey = certificate.PrivateKey;
signedDocument.KeyInfo = certificateKeyInfo;
signedDocument.ComputeSignature();
return XDocument.Parse(signedDocument.GetXml().OuterXml, LoadOptions.PreserveWhitespace);
}
private static Reference GetSignatureReference()
{
var signatureReference = new Reference("");
signatureReference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); …Run Code Online (Sandbox Code Playgroud) 所以我一直在努力使用WS-Security一段时间,慢慢取得进展.首先让我简要介绍一下我的设置.我有一个在tomcat中运行的Java应用程序,它提供了一个webservice端点(使用Spring).我想要传入消息进行签名.我正在测试SoapUI.所以经过长时间的努力,我得到服务器,只要检查传入的消息签名,我也有SoapUI,签署外发消息.但是,服务器一直拒绝证书,我不确定我在哪里做错了,即我发送了错误的证书信息与我的测试请求,或者我没有在信任库中正确维护证书.以下是请求的示例:
<soapenv:Envelope xmlns="http://movilitas.com/movilizer/v7" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp wsu:Id="Timestamp-7" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2011-06-30T12:51:33.407Z</wsu:Created>
<wsu:Expires>2011-06-30T12:53:13.407Z</wsu:Expires>
</wsu:Timestamp>
<ds:Signature Id="Signature-6" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#id-2">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>OiRQ2oXbajnnrSGsbOALT2i6brs=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
fmtFMSccFcwEfL1M8qgQ...
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-C3B38A939F7D63D51F13094382933988">
<wsse:SecurityTokenReference wsu:Id="STRId-C3B38A939F7D63D51F13094382933989" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3SubjectKeyIdentifier">
MIICbzCCAdgCAQEwDQ...
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body wsu:Id="id-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
[...]
</soapenv:Body>
</soapenv:Envelope>
Run Code Online (Sandbox Code Playgroud)
现在,当我从我的信任库(证书的base64编码版本)导出证书时,我所拥有的内容与我得到的内容相同.我发送请求时收到的错误如下:
Jul 5, 2011 4:42:23 PM com.sun.xml.wss.impl.dsig.KeySelectorImpl resolve
SEVERE: WSS1353: Error occurred while resolving key information
com.sun.xml.wss.XWSSecurityException: No Matching public key for MIICbzCCAdgCAQEwDQ... subject …Run Code Online (Sandbox Code Playgroud) 有没有人知道XPath Filter 2.0的开源实现,最好是Java?但任何其他语言也没关系.标准不是那么新,所以应该存在一些东西,但我找不到任何东西......
如果确实没有足够的东西,有没有人实现过它,并且可以告诉我使用标准方法(DOM模型加XPath)有多难?只是一个粗略的估计,对于2个全职工作的人来说,是几天还是几周?
在MSDN站点的帮助下,我可以轻松验证XML DSig是否正确.如果使用签名方法sha1,它可以完美地工作.
但是,当我收到SignatureMethod RSA-SHA512(http://www.w3.org/2001/04/xmldsig-more#rsa-sha512)时,CheckSignature()会因CryptograhicException而中断:无法为签名创建SignatureDescription算法提供.
似乎CheckSignature()无法验证RSA-SHA512签名.
有谁知道如何检查这些签名?
从MSDN站点获取的代码是:
public static bool VerifyXml(XmlDocument doc, bool removeSignatureElement = false)
{
// Check arguments.
if (doc == null)
throw new ArgumentException("doc");
// Create a new SignedXml object and pass it the XML document class.
SignedXml signedXml = new SignedXml(doc);
// Find the "Signature" node and create a new XmlNodeList object.
XmlNodeList nodeList = doc.GetElementsByTagName("Signature", Constants.NamespaceDSig);
// Throw an exception if no signature was found.
if (nodeList.Count …Run Code Online (Sandbox Code Playgroud) 如果我们以下面的Signature元素为例:
<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/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#_884D49DAD03AD60748547F8322C11AA0">
<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/2000/09/xmldsig#sha1" />
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo>
<ds:KeyName>...</ds:KeyName>
</ds:KeyInfo>
</ds:Signature>
Run Code Online (Sandbox Code Playgroud)
有SignatureMethod算法(http://www.w3.org/2000/09/xmldsig#rsa-sha1)和DigestMethod算法(http://www.w3.org/2000/09/xmldsig#sha1).
据我所知,SignatureMethod算法为'rsa-sha1'意味着要使用SHA1首先对要签名的内容进行哈希(消化),然后使用RSA进行签名.
DigestMethod算法是否总是等于SignatureMethod算法('rsa-sha1'的sha1部分)中指定的摘要机制?
我相信情况并非如此,因为两次指定相同的算法是没用的.我推测可以使用不同的DigestMethod算法消化多个'Reference',并使用SignatureMethod算法指定的摘要机制再次对这些摘要的集合进行散列.
我试图通过引用"XML签名语法和处理"规范来理解这一点.如果有人能够确认我是否理解正确,或者解释这两种算法所服务的目的,我们将非常感激.谢谢.
我正在尝试使用Spring SAML示例应用程序连接到Shibboleth IdP,但遇到了我无法解决的签名验证问题.
当示例应用程序从IdP获得响应时,将引发以下异常:
Caused by: org.opensaml.ws.security.SecurityPolicyException: Validation of protocol message signature failed
at org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule.doEvaluate(SAMLProtocolMessageXMLSignatureSecurityPolicyRule.java:138)
at org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule.evaluate(SAMLProtocolMessageXMLSignatureSecurityPolicyRule.java:107)
at org.opensaml.ws.security.provider.BasicSecurityPolicy.evaluate(BasicSecurityPolicy.java:51)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.processSecurityPolicy(BaseMessageDecoder.java:132)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.decode(BaseMessageDecoder.java:83)
at org.opensaml.saml2.binding.decoding.BaseSAML2MessageDecoder.decode(BaseSAML2MessageDecoder.java:70)
at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:105)
at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:172)
at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:80)
Run Code Online (Sandbox Code Playgroud)
随着日志包含
- Creating XMLSignature object
- Validating signature with signature algorithm URI: http://www.w3.org /2001/04/xmldsig-more#rsa-sha256
- Validation credential key algorithm 'RSA', key instance class 'sun.security.rsa.RSAPublicKeyImpl'
- Signature validated with key from supplied credential
- Signature validation using candidate credential was successful
- Successfully verified signature using KeyInfo-derived credential
- Attempting …Run Code Online (Sandbox Code Playgroud) 我试图用xmlsec1实用程序验证XML(附在问题的底部)签名.但是,在执行命令时
xmlsec1 --verify test.xml
Run Code Online (Sandbox Code Playgroud)
我正在跟踪堆栈跟踪:
func = xmlSecXPathDataExecute:file = xpath.c:line = 273:obj = unknown:subj = xmlXPtrEval:error = 5:libxml2库函数失败:expr = xpointer(id('uuid-73c06e86-88d2-4204-91f4-3d484bc782cc' ))func = xmlSecXPathDataListExecute:file = xpath.c:line = 373:obj = unknown:subj = xmlSecXPathDataExecute:error = 1:xmlsec库函数失败:func = xmlSecTransformXPathExecute:file = xpath.c:line = 483:obj = xpointer :subj = xmlSecXPathDataExecute:error = 1:xmlsec库函数失败:func = xmlSecTransformDefaultPushXml:file = transforms.c:line = 2411:obj = xpointer:subj = xmlSecTransformExecute:error = 1:xmlsec库函数失败:func = xmlSecTransformCtxXmlExecute:file = transforms.c:line = 1242:obj = unknown:subj = xmlSecTransformPushXml:error = 1:xmlsec库函数失败:transform = xpointer func = xmlSecTransformCtxExecute:file = transforms.c:line = 1302:obj = …
我需要验证签名的xml。
在C#中运行时,出现下一个错误:“遇到未知的转换。”。但是,在Java中运行它可以正确验证xml。
看起来.net框架无法识别xmldsig-filter2。在C#/。net上可以做任何事情吗?
<dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<dsig:SignedInfo>
<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<dsig:Reference Id="reference-data-0" URI="">
<dsig:Transforms>
<dsig:Transform Algorithm="http://www.w3.org/2002/06/xmldsig-filter2">
<xf2:XPath Filter="intersect" xmlns:xf2="http://www.w3.org/2002/06/xmldsig-filter2">here()/ancestor::SomeNS:SomeElement[1]</xf2:XPath>
</dsig:Transform>
<dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<dsig:DigestValue>...</dsig:DigestValue>
</dsig:Reference>
</dsig:SignedInfo>
<dsig:SignatureValue>
...
</dsig:SignatureValue>
</dsig:Signature>
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Signature ClassMicrosoft 库在 C# 中对 XML 文件进行签名。
我所做的是这样的——
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml;
using XMLSigner.Model;
using DataObject = System.Security.Cryptography.Xml.DataObject;
internal static XmlDocument GetSignedXMLDocument(XmlDocument xmlDocument, X509Certificate2 certificate, long procedureSerial = -1, string reason = "")
{
//Check if local time is OK
if(!Ntp.CheckIfLocalTimeIsOk()) {
MessageBox.Show("PC Time is need to be updated before sign !");
return null; //Last Sign Not Verified
}
//Then …Run Code Online (Sandbox Code Playgroud) 我试图将引用添加到我的安全标题,并遇到一个相当普遍的错误:
格式错误的参考元素
我尝试了以下类似的结果:
ID的元素作为的URI所述的Reference目的.XmlElement对象到Reference通过LoadXml()方法.我正在XmlElement使用此StackOverflow帖子GetIdElement上的重载找到检索引用.当我传入一个空字符串作为时URI,ComputeSignature()方法SignedXml按预期工作.但是,我需要添加最多3个对安全标头的引用.
更新#1
感谢这篇博文,我能够从中创建简化版本,我相信导致我的问题的是使用Namespace属性和前缀.
更新#2
看起来好像元素Id属性上的命名空间声明<Timestamp>导致发生此错误.
更新#3
我认为我有这个工作.请参阅下面的回答帖子.
工作示例:
请注意,Id XAttribute定义的命名空间不起作用; 而Id XAttribute没有定义的命名空间确实有效.
private void CreateSecurityAndTimestampXML(string fileName)
{
TimestampID = "TS-E" + GUID.NewGuid();
DateTime SecurityTimestampUTC = DateTime.UtcNow;
XDocument xdoc = new XDocument(
new XElement(wsse + "Security",
new XAttribute(XNamespace.Xmlns + "wsse", wsse.NamespaceName), …Run Code Online (Sandbox Code Playgroud)