gpt4 book ai didi

c# - XMLSigner 不再适用于 4.6.2 - 格式错误的引用元素

转载 作者:数据小太阳 更新时间:2023-10-29 01:45:34 28 4
gpt4 key购买 nike

将应用程序从 3.5 升级到 4.6.2 后,以下代码块不再有效。我收到“Malformed reference element”错误,即使它作为 3.5 应用程序工作得很好。代码失败并出现上述错误,这应该是一个很好的引用。我已经尝试了所有我能想到的方法,但无法使 ASP.Net 版本正常工作。我已经构建了一个测试平台版本作为控制台应用程序,它工作正常,直到它到达最后一个引用失败并显示“无法解析 Uri Signature1.jpg”。我读到 XMLSigner 不接受除 id、ID 和 Id 以外的任何元素作为查找匹配引用的元素,但我不认为是这种情况,因为它在控制台应用程序中工作。

问题的核心是:

  1. 为什么我得到的是 signedXMl.AddReference(new Reference("#Head01"));
  2. 的“格式错误的引用元素”
  3. 如何修复对客户签名“src="Signature1.jpg""的引用

有问题的功能:

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 = subjectName.Replace("S=", "ST=");
string tmpSubName = subjectName;

tmpSubName = tmpSubName.Replace("O=A", "O=B");
tmpSubName = tmpSubName.Replace("CN=A", "CN=B");

x509Data.AddSubjectName(tmpSubName);
x509Data.AddIssuerSerial(x509cert.Issuer, x509cert.GetSerialNumberString()); //GetIssuerName
keyInfo.AddClause(x509Data);
signedXml.KeyInfo = keyInfo;

//TIMESTAMP
XmlElement signaturePropertiesRoot = doc.CreateElement("SignatureProperties", "http://www.w3.org/2000/09/xmldsig#");

DataObject signatureProperties = new DataObject();
signatureProperties.Id = "TimeStamp";
signatureProperties.Data = signaturePropertiesRoot.SelectNodes(".");
signedXml.AddObject(signatureProperties);

// and add a reference to the data object
Reference propertiesRef = new Reference();
propertiesRef.Uri = "#TimeStamp";
propertiesRef.Type = "http://www.w3.org/2000/09/xmldsig#SignatureProperties";
signedXml.AddReference(propertiesRef);

XmlElement property = doc.CreateElement("SignatureProperty", "http://www.w3.org/2000/09/xmldsig#");
property.SetAttribute("Id", "TamperSealer01TimeStamp");
property.SetAttribute("Target", "#" + signedXml.Signature.Id);
signaturePropertiesRoot.AppendChild(property);

XmlElement timestamp = doc.CreateElement("DateTimeStamp", "http://www.w3.org/2000/09/xmldsig#");
timestamp.SetAttribute("DateTime", String.Format("{0:s}Z", DateTime.Now.ToUniversalTime()));
property.AppendChild(timestamp);
signedXml.ComputeSignature();

// References contains three strings "Head01", "Data01", and "View01"
foreach (string docRef in references)
{
// Create a reference to be signed.
Reference tempRef = new Reference();
tempRef.Uri = "#" + docRef;
Logger.Current.LogInformation("DocRef: #" + docRef + ".");
// Add the reference to the SignedXml object
signedXml.AddReference(tempRef);
signedXml.ComputeSignature(); //Immediately Fails here
}

// alSignatures only contains "Signature1.jpg" in this case. Don't yell at me for this crappy code, I didn't write it and plan on fixing it when everything else works.
int ctr = 0;
foreach (string str in alSignatures)
{
Reference testRef = new Reference();
Uri relativeUri = new Uri(alSignatures[ctr].ToString(), UriKind.RelativeOrAbsolute);
Logger.Current.LogInformation("Signature Reference: " + alSignatures[ctr].ToString());
testRef.Uri = alSignatures[ctr].ToString();
signedXml.AddReference(testRef);
ctr += 1;
}

// Compute the signature.
signedXml.ComputeSignature();

// Get the XML representation of the signature and save it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
XmlElement signaturesElement = doc.CreateElement("SIGNATURES", "http://www.mismo.org");

signaturesElement.AppendChild(signedXml.GetXml());
doc.DocumentElement.AppendChild(signaturesElement);

key.Clear();
key.Dispose();
return doc;
}

它应该签署的 XML 是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<DOCUMENT MISMOVersionIdentifier="1.02">
<HEADER _ID="Head01">
<SIGNATURE_MODEL>
<SIGNER AreaIDREF="Borrower1SignatureArea" SectionIDREF="BorrowerSignatures" SignatureIDREF="Borrower1SignatureLine" SignatureType="Image" TargetsIDREFS="View01" _RoleType="Borrower" _SignatureOrderNumber="1" />
<SIGNER SignatureIDREF="TamperSealer01" SignatureType="DigitalSignature" TargetsIDREFS="Head01 Data01 View01" _RoleType="TamperSealer" _SignatureOrderNumber="1" />
</SIGNATURE_MODEL>
</HEADER>
<DATA _ID="Data01">
<MAIN>
</MAIN>
</DATA>
<VIEW _ID="View01" _MIMETypeDescription="text/html" _TaggedIndicator="True">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<span class="dataEntered" id="BORROWER_Signer-Info">
<SIGNATURE_SECTION _ID="BorrowerSignatures">
<SIGNATURE_AREA _ID="Borrower1SignatureArea">
<p class="right">
<SIGNATURE_ABOVE_LINE />
<SIGNATURE_IMAGE _EncodingTypeDescription="None" _ID="Borrower1SignatureLine" _MIMEType="image/jpeg">
<img align="right" alt="Signature file is missing - Invalid Document" src="Signature1.jpg" />
</SIGNATURE_IMAGE>
</p>
<p>04/12/2011 12:00 PM</p>
</SIGNATURE_AREA>
</SIGNATURE_SECTION>
</span>
</body>
</html>
</VIEW>
</DOCUMENT>

最佳答案

System.Security.Cryptography.Xml.Reference的相关代码——CalculateHashValue:

// for "Head01" this is "#Head01"
if (this.m_uri[0] == '#')
{
// idFromLocalUri is set to "Head01"
string idFromLocalUri = Utils.GetIdFromLocalUri(this.m_uri, out flag);
...
// there is no element with Id="Head01" - so xmlElement is null
var xmlElement = this.SignedXml.GetIdElement(document, idFromLocalUri);
...
if (xmlElement == null)
{
// this is the error you're getting
throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidReference"));
}
}

所以你在引用验证上失败了——文档中没有带有这个 id 的元素——顺便说一句。实验性地将 xml 中的“_ID”更改为“Id”解决了这个问题。

好消息是 SignedXml 类是可扩展的,您可以重载 XmlElement GetIdElement(XmlDocument document, string idValue) 方法以将“_ID”纳入帐户。

// just a sample
class MyCustomSignedXml : SignedXml {
...
override XmlElement GetIdElement(XmlDocument document, string idValue) {
var element = document.SelectSingleNode($"//*[@_ID='{idValue}']") as XmlElement;
if (element != null) {
return element;
}

return base.GetIdElement(document, idValue);
}
}

关于c# - XMLSigner 不再适用于 4.6.2 - 格式错误的引用元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46042076/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com