我收到了第三方网络服务的回复.我加载了一个带有该响应的XmlDocument.
string txt = readStream.ReadToEnd();
response = new XmlDocument();
response.PreserveWhitespace = true;
response.LoadXml(txt);
return response;
Run Code Online (Sandbox Code Playgroud)
现在我想验证响应是否使用证书签名.我有一个VerifyXmlDoc(XmlDocument xmlDoc)我在msdn上找到的方法.
我知道这条消息是正确的.
public bool VerifyXmlDoc(XmlDocument xmlDoc)
{
SignedXml signed = new SignedXml(xmlDoc);
XmlNodeList signatureNodeList = xmlDoc.GetElementsByTagName("Signature");
signed.LoadXml((XmlElement)signatureNodeList[0]);
X509Certificate2 serviceCertificate = null;
foreach (KeyInfoClause clause in signed.KeyInfo)
{
if (clause is KeyInfoX509Data)
{
if (((KeyInfoX509Data)clause).Certificates.Count > 0)
{
serviceCertificate = (X509Certificate2)((KeyInfoX509Data)clause).Certificates[0];
}
}
}
bool result = signed.CheckSignature(serviceCertificate, true);
return result;
}
Run Code Online (Sandbox Code Playgroud)
如果我将我的项目的目标框架设置为.NET 3.5或.NET 3,或.NET 2,它的工作原理很棒.结果是真的.但是如果我将目标框架更改为.NET 4,则结果为false.(我必须使用.NET 4)
关于如何解决这个问题的任何想法?
当我签署包含名称空间前缀和名称空间引用的XML文档然后验证它时,会出现问题.在这种情况下,验证总是失败(返回false).当我从XML中删除名称空间前缀和名称空间引用时,签名和验证工作正常.
你可以帮帮我吗 ?
这是我的代码:
SignedXml的继承类
namespace Xmldsig
{
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;
public sealed class SignaturePropertiesSignedXml : SignedXml
{
private XmlDocument doc;
private XmlElement signaturePropertiesRoot;
private XmlElement qualifyingPropertiesRoot;
private string signaturePropertiesId;
public SignaturePropertiesSignedXml(XmlDocument doc)
: base(doc)
{
return;
}
public SignaturePropertiesSignedXml(XmlDocument doc, string signatureId, string propertiesId)
: base(doc)
{
this.signaturePropertiesId = propertiesId;
this.doc = null;
this.signaturePropertiesRoot = null;
if (string.IsNullOrEmpty(signatureId))
{
throw new ArgumentException("signatureId cannot be empty", "signatureId");
}
if (string.IsNullOrEmpty(propertiesId))
{
throw new ArgumentException("propertiesId cannot …Run Code Online (Sandbox Code Playgroud) 在Windows 2003服务器上使用VS 2008和.Net Framework 3.5.
为了安全起见,我们使用SAML实施了SSO.我们在服务提供商端工作,我们验证从客户端系统生成的签名XML SAML Assertuib令牌.截至目前,我们遇到的任何签名文档都使用了签名算法"rsa-sha1",但现在我们有新客户发送带有签名算法的文件"rsa-sha256",这就是问题的开始.
public static string VerifySignature()
{
if (m_xmlDoc == null)
return "Could not load XMLDocument ";
try
{
XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable());
nsm.AddNamespace("dsig", SignedXml.XmlDsigNamespaceUrl);
XmlElement sigElt = (XmlElement)m_xmlDoc.SelectSingleNode(
"//dsig:Signature", nsm);
// Load the signature for verification
SignedXml sig = new SignedXml(m_xmlDoc);
sig.LoadXml(sigElt);
if (!sig.CheckSignature())
return "Invalid Signature";
}
catch (Exception ex)
{
return ex.Message;
}
return string.Empty;
}
Run Code Online (Sandbox Code Playgroud)
现在,当我为这个新客户尝试相同的代码(使用签名算法rsa-sha256h)时 - 这不起作用,我收到错误"无法为提供的签名算法创建SignatureDescription."
在过去2-3天内浏览了许多博客和文章,我发现SignedXml不支持sha256.精细.但接下来是什么.在其提到的某个地方使用WIF,我也检查过并试过这个.
我也在尝试使用RSAPKCS1SignatureDeformatter的VerifySignature方法.但不确定要传递的两个参数是什么.
将应用程序从3.5升级到4.6.2后面的代码块不再有效.我得到"格式错误的参考元素"错误,即使它作为3.5应用程序工作得很好.代码失败,上面的错误应该是一个很好的参考.我已经尝试了我能想到的一切都无法让ASP.Net版本正常工作.我已经构建了一个测试版本作为控制台应用程序,它可以正常工作,直到它到达最后一个失败并且"无法解析Uri Signature1.jpg"的引用.我已经读过XMLSigner不接受除id,ID和Id之外的任何内容作为匹配引用的元素,但是我不相信这是因为它适用于控制台应用程序.
问题的核心是:
signedXMl.AddReference(new Reference("#Head01"));有问题的功能:
private XmlDocument SignDoc(XmlDocument doc, RSA key, X509Certificate x509cert, ArrayList alSignatures)
{
string signatureID = "TamperSealer01";
Uri uri = new Uri(ConfigurationManager.AppSettings["SomeSetting"]);
XmlResolver resolver = new XmlSignatureResolver(uri);
SignedXml signedXml = new SignedXml(doc);
signedXml.Signature.Id = signatureID;
signedXml.Resolver = resolver;
// Add the key to the SignedXml responseDocument.
signedXml.SigningKey = key;
// Create a new KeyInfo object.
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new RSAKeyValue(key));
KeyInfoX509Data x509Data = new KeyInfoX509Data(x509cert);
string subjectName = x509cert.Subject;
subjectName = …Run Code Online (Sandbox Code Playgroud) 我有一个格式良好的XML,没有任何空格.它必须是那样的.
当我将它加载到XMLDocument进行签名时,自闭标签会获得额外的空白区域
<cEAN/>
Run Code Online (Sandbox Code Playgroud)
变为:
<cEAN />
Run Code Online (Sandbox Code Playgroud)
一旦签署此文档,就无法删除空白区域.
PreserveWhiteSpace属性对结果没有任何影响.
我该如何改变这种行为?
我使用以下方法签署Xml文档:
public static XmlDocument SignDocument(XmlDocument doc)
{
string signatureCanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
string signatureMethod = @"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
string digestMethod = @"http://www.w3.org/2001/04/xmlenc#sha256";
string signatureReferenceURI = "#_73e63a41-156d-4fda-a26c-8d79dcade713";
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), signatureMethod);
var signingCertificate = GetCertificate();
SignedXml signer = new SignedXml(doc);
signer.SigningKey = signingCertificate.PrivateKey;
signer.KeyInfo = new KeyInfo();
signer.KeyInfo.AddClause(new KeyInfoX509Data(signingCertificate));
signer.SignedInfo.CanonicalizationMethod = signatureCanonicalizationMethod;
signer.SignedInfo.SignatureMethod = signatureMethod;
XmlDsigEnvelopedSignatureTransform envelopeTransform = new XmlDsigEnvelopedSignatureTransform();
XmlDsigExcC14NTransform cn14Transform = new XmlDsigExcC14NTransform();
Reference signatureReference = new Reference();
signatureReference.Uri = signatureReferenceURI;
signatureReference.AddTransform(envelopeTransform);
signatureReference.AddTransform(cn14Transform);
signatureReference.DigestMethod = digestMethod;
signer.AddReference(signatureReference);
signer.ComputeSignature();
XmlElement signatureElement = signer.GetXml();
doc.DocumentElement.AppendChild(signer.GetXml());
return …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用System.Security.Cryptography(目标框架.NET 4.5)来创建xml数字签名,到目前为止,我设法使用以下方案创建和验证签名:RSA PKCS#1 v1.5和SHA-256:http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
但是,我无法使用以下方案:'没有使用SHA-256参数的RSASSA-PSS'[RFC6931]:http://www.w3.org/2007/05/xmldsig-more#sha256-rsa- MGF1
显示的错误很明显"无法为提供的签名算法创建SignatureDescription."
对于'RSA PKCS#1 v1.5和SHA-256',我添加了以下公共类作为其签名:
public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
{
public RSAPKCS1SHA256SignatureDescription()
{
base.KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
base.DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
base.FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
base.DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
}
public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
AsymmetricSignatureDeformatter asymmetricSignatureDeformatter = (AsymmetricSignatureDeformatter)
CryptoConfig.CreateFromName(base.DeformatterAlgorithm);
asymmetricSignatureDeformatter.SetKey(key);
asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256");
return asymmetricSignatureDeformatter;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我不知道.Net 4.5是否支持'使用SHA-256没有参数的RSASSA-PSS',如果是的话,如何设置其签名定义.
如果有人有类似的经验并能提供一些帮助,我会非常感激.
我一直在努力使.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) 是否可以使用带有SignedXml的http://www.w3.org/2006/12/xml-c14n11 CanonicalizationMethod?
SignedXml signedXml = new SignedXml(xmlDoc);
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2006/12/xml-c14n11";
Run Code Online (Sandbox Code Playgroud)
扔了
System.Security.Cryptography.CryptographicException: Could not create the XML tr
ansformation identified by the URI http://www.w3.org/2006/12/xml-c14n11.
Run Code Online (Sandbox Code Playgroud)
谢谢!
我们正在从使用 java 的第三方接收签名的 xml。我们的 .NET 实现会正确验证签名,除非 xml 包含 字符参考。
看起来 .NET 在 c14n 进程中的某处删除了该换行符。
我用下一个 xml 在 c# 中运行了一些测试:
var xml = "<a>something \nsomething\r\n</a>";
Run Code Online (Sandbox Code Playgroud)
使用 c14n 的下一个代码:
public static void c14n(string xml)
{
using (MemoryStream msIn = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
var t = new XmlDsigExcC14NTransform(false);
t.LoadInput(msIn);
var o = t.GetOutput() as MemoryStream;
var c14n = Encoding.UTF8.GetString((o as MemoryStream).ToArray());
Console.WriteLine(c14n);
}
}
Run Code Online (Sandbox Code Playgroud)
将产生下一个 xml,这符合w3org规范(每行以 LF 字符结尾):
<a>something
something
</a>
Run Code Online (Sandbox Code Playgroud)
但是,当使用下一个代码查看具有 SignedXml .NET 类签名的 xml 的规范形式时:
public static void SignXml(string …Run Code Online (Sandbox Code Playgroud) c# ×10
signedxml ×10
.net ×3
xml ×3
asp.net ×1
c#-4.0 ×1
c14n ×1
certificate ×1
cryptography ×1
saml ×1
security ×1
sha256 ×1
signature ×1
xmldocument ×1