我正在尝试签署一些XML文件,我设法做得很好,但我找不到检查签名的方法,接收器服务接受它(xml),但它在签名上发现错误
我已检查过Web服务的文档,他们说,签名值每行最多可包含76个字符,每次加载或编辑xml文件时都必须保留.whitespace。
这是我输出的xml文件(为了安全起见我编辑了一些值) puu.sh/d6lwC/25eb2a0d02.png(注意两个签名值是如何是一条没有间距的长行。
我认为这应该是这样的: puu.sh/d6lCV/48b0cc0cd7.png
根据服务文档,这是xml文件: puu.sh/d6ltJ/bd8e25a4b4.png
这是我的签名代码
SignedXml signedXml = new SignedXml(xmldocument);
signedXml.SigningKey = certificado.PrivateKey;
Signature XMLSignature = signedXml.Signature;
Reference reference = new Reference();
reference.Uri = referenciaUri;
XMLSignature.SignedInfo.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new RSAKeyValue((RSA)certificado.PrivateKey));
keyInfo.AddClause(new KeyInfoX509Data(certificado));
XMLSignature.KeyInfo = keyInfo;
signedXml.ComputeSignature();
XmlElement xmlDigitalSignature = signedXml.GetXml();
xmldocument.DocumentElement.SelectSingleNode(para).AppendChild(xmldocument.ImportNode(xmlDigitalSignature, true));
我的问题是:
如何在不损坏xml本身的其他核心值的情况下轻松分割签名值的行,以便通过该更改使Web服务能够正确读取和验证xml文件的签名?
先谢谢,原谅我糟糕的英语。
他以某种方式来解决我的问题,通过php用块分割base64值和76长度用这段代码
// Base64 encoding
$SignatureValue = rtrim(chunk_split(base64_encode($SignatureValue_bruto), 76));
我怎样才能用c#实现这个目标?
答案 0 :(得分:1)
有点旧,但我觉得让dotNet为你做这样的工作要简单得多:
var bytes = Convert.FromBase64String(str);
return Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
答案 1 :(得分:0)
好的!你可以试试这个:-) 添加以下代码
public static string base64_encode(string str)
{
return System.Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
}
public static string chunk_split(string str, int len)
{
var strings = new List<string>();
var div = str.Length % len;
var remainder = len - div * len;
if (div == 1)
{
return string.Join("", str.Take(len));
}
for (var j = 0; j < div; j++)
{
var s = string.Join("", str.Skip(j * len).Take(len));
if (!string.IsNullOrEmpty(s))
strings.Add(s);
}
if (remainder > 0)
{
var s = string.Join("", str.Skip(div * len).Take(remainder));
if (!string.IsNullOrEmpty(s))
strings.Add(s);
}
return string.Join(Environment.NewLine, strings.ToArray());
}
public static string rtrim(string input)
{
while (input.EndsWith(Environment.NewLine))
input = input.Remove(input.Length - Environment.NewLine.Length);
return input.TrimEnd(' ');
}
然后只需使用
chunk_split(base64_encode(strstr), 76);
编辑您可以使用此功能修复文档的签名。我不知道我还能帮助你:P
public static void UpdateXmlSignature(string filename)
{
// Load the target xml, the xml file with the certificate
var doc = XDocument.Load(filename);
var cert = doc.XPathSelectElement("//X509Data/X509Certificate");
if (cert != null)
{
var updatedValue = rtrim(chunk_split(base64_encode(cert.Value), 76));
cert.Value = updatedValue;
}
// Overwrite the old file
doc.Save(filename);
}
这将要求所有代码都到位。