sun*_*r20 8 c# xml asp.net cryptography signedxml
将应用程序从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 = 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;
}
Run Code Online (Sandbox Code Playgroud)
因此,它应签署的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>
Run Code Online (Sandbox Code Playgroud)
相关代码CalculateHashValue段System.Security.Cryptography.Xml.Reference:
// 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"));
}
}
Run Code Online (Sandbox Code Playgroud)
所以你在参考验证上失败了 - 文档中没有具有此 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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
822 次 |
| 最近记录: |