参考 KeyInfo 为 XML 创建数字签名
Create Digital Signature for XML with reference to KeyInfo
我需要根据 ISO20022 标准为 XML 创建数字签名。
该示例显示了 3 个引用,其中一个用于 KeyInfo 元素(具有 #_33d232d2-4591-4b49-b28d-3cb825fbeaa4 URI 的那个)。
<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="#_33d232d2-4591-4b49-b28d-3cb825fbeaa4">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>h9toHGSlK/x1zE7egK0yEj06W2D9wAEK/VAuiwU8+R8=</ds:DigestValue>
</ds:Reference>
<ds:Reference Type="http://uri.etsi.org/01903/v1.3.2#SignedProperties" URI="#_aba0ee84-5f37-499e-a8e8-caa7f398341c-signedprops">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>Ot7tqqOtgtguRadTQi0fh5FU3XL/4/mHIv7Eoy67t/s=</ds:DigestValue>
</ds:Reference>
<ds:Reference>
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>1ZZln0/NzN/eB1wIrxyp/c3SOjKWnk00Lh1bKTXlTAE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>VRn+Q7K6snvKrFPwtH302iKPjAx1k97TKIvjysdH+/I8EMyzWg20gZ1fO1gjKk245nfzXIsiuoVIZJtBKNSE9Tp+VXegJxyAoXx1bz8fMZIbdjjhXaYzdx2yCGh9Fllrbg+y9RZy9VvG7sLQeu91gOge7GHNIxO6jck96yVsY8k=</ds:SignatureValue>
<ds:KeyInfo Id="_33d232d2-4591-4b49-b28d-3cb825fbeaa4">
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>C=SE, O=CMA Small Systems AB, CN=Test CA</ds:X509IssuerName>
<ds:X509SerialNumber>12345678</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</ds:KeyInfo>
<ds:Object>
<xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#">
<xades:SignedProperties Id="_aba0ee84-5f37-499e-a8e8-caa7f398341csignedprops">
<xades:SignedSignatureProperties>
<xades:SigningTime>2019-08-23T19:01:41+12:00</xades:SigningTime>
</xades:SignedSignatureProperties>
</xades:SignedProperties>
</xades:QualifyingProperties>
</ds:Object>
</ds:Signature>
然而,当我尝试对 .NET 6 执行相同操作时,出现以下异常
System.Security.Cryptography.CryptographicException: Malformed reference element.
at System.Security.Cryptography.Xml.Reference.CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList)
at System.Security.Cryptography.Xml.Reference.UpdateHashValue(XmlDocument document, CanonicalXmlNodeList refList)
at System.Security.Cryptography.Xml.SignedXml.BuildDigestedReferences()
at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()
检查 SignedXml class,BuildDigestedReferences
方法中的 CanonicalXmlNodeList
似乎缺少 KeyInfo。有什么解决办法吗?
这是我签署 XML
的代码
static void SignXmlWithCert(XmlDocument doc, X509Certificate2 cert)
{
const string signedPropsIdSuffix = "-signedprops";
var signedXml = new SignedXml(doc)
{
SigningKey = cert.GetRSAPrivateKey()
};
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
var idKeyInfo = "_" + Guid.NewGuid();
var idKeyInfoProps = "_" + Guid.NewGuid() + signedPropsIdSuffix;
#region keyinfo
var keyInfo = new KeyInfo();
var keydata = new KeyInfoX509Data(cert, X509IncludeOption.None);
keydata.AddIssuerSerial(cert.Issuer, cert.SerialNumber);
keyInfo.AddClause(keydata);
keyInfo.Id = idKeyInfo;
signedXml.KeyInfo = keyInfo;
#endregion keyinfo
#region References
var transform = new XmlDsigEnvelopedSignatureTransform() { Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#" };
var references = new List<Reference>();
// first reference
var keyInfoReference = new Reference();
keyInfoReference.Uri = "#" + keyInfo.Id;
keyInfoReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
keyInfoReference.AddTransform(transform);
references.Add(keyInfoReference);
//second reference
var signaturePropertiesReference = new Reference();
signaturePropertiesReference.Type = "http://uri.etsi.org/01903/v1.3.2#SignedProperties";
signaturePropertiesReference.Uri = "#" + idKeyInfoProps;
signaturePropertiesReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signaturePropertiesReference.AddTransform(transform);
references.Add(signaturePropertiesReference);
//third reference
var documentReference = new Reference();
documentReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
documentReference.AddTransform(transform);
references.Add(documentReference);
foreach (var reference in references)
{
signedXml.AddReference(reference);
}
#endregion
#region 4. Set up <ds:Object> with <QualifiyingProperties> inside that includes SigningTime
var URI = "http://uri.etsi.org/01903/v1.3.2#";
var qualifyingPropertiesRoot = doc.CreateElement("xades", "QualifyingProperties", URI);
var signaturePropertiesRoot = doc.CreateElement("xades", "SignedProperties", URI);
signaturePropertiesRoot.SetAttribute("Id", idKeyInfoProps);
var SignedSignatureProperties = doc.CreateElement("xades", "SignedSignatureProperties", URI);
var timestamp = doc.CreateElement("xades", "SigningTime", URI);
timestamp.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"); // primero de la lista
signaturePropertiesRoot.AppendChild(SignedSignatureProperties);
SignedSignatureProperties.AppendChild(timestamp);
qualifyingPropertiesRoot.AppendChild(signaturePropertiesRoot);
var qualifyingPropertiesObject = new DataObject
{
Data = qualifyingPropertiesRoot.SelectNodes("."),
Id = idKeyInfoProps
};
signedXml.AddObject(qualifyingPropertiesObject);
#endregion
signedXml.ComputeSignature();
}
it seems that KeyInfo is missing from the CanonicalXmlNodeList in the BuildDigestedReferences method.
那是因为它不是文档的一部分。
Is there any way around this?
将其添加到文档中。我没有尝试手动构建它,而是修改了您的代码以制作两个不同的 SignedXml 对象,一个将节点放入待签名的对象中,另一个进行最终签名。
注释掉的代码行是我必须更改或删除以使您的代码段正常工作的行。
static void SignXmlWithCert(XmlDocument doc, X509Certificate2 cert)
{
const string signedPropsIdSuffix = "-signedprops";
var signedXml = new SignedXml(doc)
{
SigningKey = cert.GetRSAPrivateKey()
};
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
var idKeyInfo = "_" + Guid.NewGuid();
var idKeyInfoProps = "_" + Guid.NewGuid() + signedPropsIdSuffix;
#region keyinfo
var keyInfo = new KeyInfo();
var keydata = new KeyInfoX509Data(cert, X509IncludeOption.None);
keydata.AddIssuerSerial(cert.Issuer, cert.SerialNumber);
keyInfo.AddClause(keydata);
keyInfo.Id = idKeyInfo;
signedXml.KeyInfo = keyInfo;
#endregion keyinfo
#region References
//var transform = new XmlDsigEnvelopedSignatureTransform() { Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#" };
var transform = new XmlDsigExcC14NTransform();
var references = new List<Reference>();
// first reference
var keyInfoReference = new Reference();
keyInfoReference.Uri = "#" + keyInfo.Id;
keyInfoReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
keyInfoReference.AddTransform(transform);
references.Add(keyInfoReference);
//second reference
var signaturePropertiesReference = new Reference();
signaturePropertiesReference.Type = "http://uri.etsi.org/01903/v1.3.2#SignedProperties";
signaturePropertiesReference.Uri = "#" + idKeyInfoProps;
signaturePropertiesReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signaturePropertiesReference.AddTransform(transform);
references.Add(signaturePropertiesReference);
//third reference
var documentReference = new Reference();
documentReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
// The code in the question didn't assign Uri, and since no transform did an inherent
// node resolution, signing failed.
documentReference.Uri = "";
documentReference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
documentReference.AddTransform(transform);
references.Add(documentReference);
foreach (Reference reference in references)
{
signedXml.AddReference(reference);
}
#endregion
#region 4. Set up <ds:Object> with <QualifiyingProperties> inside that includes SigningTime
var URI = "http://uri.etsi.org/01903/v1.3.2#";
XmlElement qualifyingPropertiesRoot = doc.CreateElement("xades", "QualifyingProperties", URI);
XmlElement signaturePropertiesRoot = doc.CreateElement("xades", "SignedProperties", URI);
signaturePropertiesRoot.SetAttribute("Id", idKeyInfoProps);
XmlElement SignedSignatureProperties = doc.CreateElement("xades", "SignedSignatureProperties", URI);
XmlElement timestamp = doc.CreateElement("xades", "SigningTime", URI);
timestamp.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"); // primero de la lista
signaturePropertiesRoot.AppendChild(SignedSignatureProperties);
SignedSignatureProperties.AppendChild(timestamp);
qualifyingPropertiesRoot.AppendChild(signaturePropertiesRoot);
var qualifyingPropertiesObject = new DataObject
{
Data = qualifyingPropertiesRoot.SelectNodes("."),
//Id = idKeyInfoProps
};
signedXml.AddObject(qualifyingPropertiesObject);
#endregion
SignedXml tmp = new SignedXml(doc)
{
SigningKey = signedXml.SigningKey,
KeyInfo = signedXml.KeyInfo,
};
foreach (DataObject obj in signedXml.Signature.ObjectList)
{
tmp.AddObject(obj);
}
tmp.AddReference(new Reference(""));
tmp.ComputeSignature();
XmlTextWriter prettyOut = new XmlTextWriter(System.Console.Out);
prettyOut.Formatting = Formatting.Indented;
Console.WriteLine("Original document");
doc.WriteTo(prettyOut);
Console.WriteLine();
Console.WriteLine();
XmlElement elem = tmp.GetXml();
doc.DocumentElement.AppendChild(elem);
Console.WriteLine("Stage 1 signed");
doc.WriteTo(prettyOut);
Console.WriteLine();
Console.WriteLine();
signedXml.ComputeSignature();
doc.DocumentElement.RemoveChild(elem);
doc.DocumentElement.AppendChild(signedXml.GetXml());
Console.WriteLine("Stage 2 signed");
doc.WriteTo(prettyOut);
}
我需要根据 ISO20022 标准为 XML 创建数字签名。
该示例显示了 3 个引用,其中一个用于 KeyInfo 元素(具有 #_33d232d2-4591-4b49-b28d-3cb825fbeaa4 URI 的那个)。
<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="#_33d232d2-4591-4b49-b28d-3cb825fbeaa4">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>h9toHGSlK/x1zE7egK0yEj06W2D9wAEK/VAuiwU8+R8=</ds:DigestValue>
</ds:Reference>
<ds:Reference Type="http://uri.etsi.org/01903/v1.3.2#SignedProperties" URI="#_aba0ee84-5f37-499e-a8e8-caa7f398341c-signedprops">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>Ot7tqqOtgtguRadTQi0fh5FU3XL/4/mHIv7Eoy67t/s=</ds:DigestValue>
</ds:Reference>
<ds:Reference>
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>1ZZln0/NzN/eB1wIrxyp/c3SOjKWnk00Lh1bKTXlTAE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>VRn+Q7K6snvKrFPwtH302iKPjAx1k97TKIvjysdH+/I8EMyzWg20gZ1fO1gjKk245nfzXIsiuoVIZJtBKNSE9Tp+VXegJxyAoXx1bz8fMZIbdjjhXaYzdx2yCGh9Fllrbg+y9RZy9VvG7sLQeu91gOge7GHNIxO6jck96yVsY8k=</ds:SignatureValue>
<ds:KeyInfo Id="_33d232d2-4591-4b49-b28d-3cb825fbeaa4">
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>C=SE, O=CMA Small Systems AB, CN=Test CA</ds:X509IssuerName>
<ds:X509SerialNumber>12345678</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</ds:KeyInfo>
<ds:Object>
<xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#">
<xades:SignedProperties Id="_aba0ee84-5f37-499e-a8e8-caa7f398341csignedprops">
<xades:SignedSignatureProperties>
<xades:SigningTime>2019-08-23T19:01:41+12:00</xades:SigningTime>
</xades:SignedSignatureProperties>
</xades:SignedProperties>
</xades:QualifyingProperties>
</ds:Object>
</ds:Signature>
然而,当我尝试对 .NET 6 执行相同操作时,出现以下异常
System.Security.Cryptography.CryptographicException: Malformed reference element.
at System.Security.Cryptography.Xml.Reference.CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList)
at System.Security.Cryptography.Xml.Reference.UpdateHashValue(XmlDocument document, CanonicalXmlNodeList refList)
at System.Security.Cryptography.Xml.SignedXml.BuildDigestedReferences()
at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()
检查 SignedXml class,BuildDigestedReferences
方法中的 CanonicalXmlNodeList
似乎缺少 KeyInfo。有什么解决办法吗?
这是我签署 XML
的代码static void SignXmlWithCert(XmlDocument doc, X509Certificate2 cert)
{
const string signedPropsIdSuffix = "-signedprops";
var signedXml = new SignedXml(doc)
{
SigningKey = cert.GetRSAPrivateKey()
};
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
var idKeyInfo = "_" + Guid.NewGuid();
var idKeyInfoProps = "_" + Guid.NewGuid() + signedPropsIdSuffix;
#region keyinfo
var keyInfo = new KeyInfo();
var keydata = new KeyInfoX509Data(cert, X509IncludeOption.None);
keydata.AddIssuerSerial(cert.Issuer, cert.SerialNumber);
keyInfo.AddClause(keydata);
keyInfo.Id = idKeyInfo;
signedXml.KeyInfo = keyInfo;
#endregion keyinfo
#region References
var transform = new XmlDsigEnvelopedSignatureTransform() { Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#" };
var references = new List<Reference>();
// first reference
var keyInfoReference = new Reference();
keyInfoReference.Uri = "#" + keyInfo.Id;
keyInfoReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
keyInfoReference.AddTransform(transform);
references.Add(keyInfoReference);
//second reference
var signaturePropertiesReference = new Reference();
signaturePropertiesReference.Type = "http://uri.etsi.org/01903/v1.3.2#SignedProperties";
signaturePropertiesReference.Uri = "#" + idKeyInfoProps;
signaturePropertiesReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signaturePropertiesReference.AddTransform(transform);
references.Add(signaturePropertiesReference);
//third reference
var documentReference = new Reference();
documentReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
documentReference.AddTransform(transform);
references.Add(documentReference);
foreach (var reference in references)
{
signedXml.AddReference(reference);
}
#endregion
#region 4. Set up <ds:Object> with <QualifiyingProperties> inside that includes SigningTime
var URI = "http://uri.etsi.org/01903/v1.3.2#";
var qualifyingPropertiesRoot = doc.CreateElement("xades", "QualifyingProperties", URI);
var signaturePropertiesRoot = doc.CreateElement("xades", "SignedProperties", URI);
signaturePropertiesRoot.SetAttribute("Id", idKeyInfoProps);
var SignedSignatureProperties = doc.CreateElement("xades", "SignedSignatureProperties", URI);
var timestamp = doc.CreateElement("xades", "SigningTime", URI);
timestamp.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"); // primero de la lista
signaturePropertiesRoot.AppendChild(SignedSignatureProperties);
SignedSignatureProperties.AppendChild(timestamp);
qualifyingPropertiesRoot.AppendChild(signaturePropertiesRoot);
var qualifyingPropertiesObject = new DataObject
{
Data = qualifyingPropertiesRoot.SelectNodes("."),
Id = idKeyInfoProps
};
signedXml.AddObject(qualifyingPropertiesObject);
#endregion
signedXml.ComputeSignature();
}
it seems that KeyInfo is missing from the CanonicalXmlNodeList in the BuildDigestedReferences method.
那是因为它不是文档的一部分。
Is there any way around this?
将其添加到文档中。我没有尝试手动构建它,而是修改了您的代码以制作两个不同的 SignedXml 对象,一个将节点放入待签名的对象中,另一个进行最终签名。
注释掉的代码行是我必须更改或删除以使您的代码段正常工作的行。
static void SignXmlWithCert(XmlDocument doc, X509Certificate2 cert)
{
const string signedPropsIdSuffix = "-signedprops";
var signedXml = new SignedXml(doc)
{
SigningKey = cert.GetRSAPrivateKey()
};
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
var idKeyInfo = "_" + Guid.NewGuid();
var idKeyInfoProps = "_" + Guid.NewGuid() + signedPropsIdSuffix;
#region keyinfo
var keyInfo = new KeyInfo();
var keydata = new KeyInfoX509Data(cert, X509IncludeOption.None);
keydata.AddIssuerSerial(cert.Issuer, cert.SerialNumber);
keyInfo.AddClause(keydata);
keyInfo.Id = idKeyInfo;
signedXml.KeyInfo = keyInfo;
#endregion keyinfo
#region References
//var transform = new XmlDsigEnvelopedSignatureTransform() { Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#" };
var transform = new XmlDsigExcC14NTransform();
var references = new List<Reference>();
// first reference
var keyInfoReference = new Reference();
keyInfoReference.Uri = "#" + keyInfo.Id;
keyInfoReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
keyInfoReference.AddTransform(transform);
references.Add(keyInfoReference);
//second reference
var signaturePropertiesReference = new Reference();
signaturePropertiesReference.Type = "http://uri.etsi.org/01903/v1.3.2#SignedProperties";
signaturePropertiesReference.Uri = "#" + idKeyInfoProps;
signaturePropertiesReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signaturePropertiesReference.AddTransform(transform);
references.Add(signaturePropertiesReference);
//third reference
var documentReference = new Reference();
documentReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
// The code in the question didn't assign Uri, and since no transform did an inherent
// node resolution, signing failed.
documentReference.Uri = "";
documentReference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
documentReference.AddTransform(transform);
references.Add(documentReference);
foreach (Reference reference in references)
{
signedXml.AddReference(reference);
}
#endregion
#region 4. Set up <ds:Object> with <QualifiyingProperties> inside that includes SigningTime
var URI = "http://uri.etsi.org/01903/v1.3.2#";
XmlElement qualifyingPropertiesRoot = doc.CreateElement("xades", "QualifyingProperties", URI);
XmlElement signaturePropertiesRoot = doc.CreateElement("xades", "SignedProperties", URI);
signaturePropertiesRoot.SetAttribute("Id", idKeyInfoProps);
XmlElement SignedSignatureProperties = doc.CreateElement("xades", "SignedSignatureProperties", URI);
XmlElement timestamp = doc.CreateElement("xades", "SigningTime", URI);
timestamp.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"); // primero de la lista
signaturePropertiesRoot.AppendChild(SignedSignatureProperties);
SignedSignatureProperties.AppendChild(timestamp);
qualifyingPropertiesRoot.AppendChild(signaturePropertiesRoot);
var qualifyingPropertiesObject = new DataObject
{
Data = qualifyingPropertiesRoot.SelectNodes("."),
//Id = idKeyInfoProps
};
signedXml.AddObject(qualifyingPropertiesObject);
#endregion
SignedXml tmp = new SignedXml(doc)
{
SigningKey = signedXml.SigningKey,
KeyInfo = signedXml.KeyInfo,
};
foreach (DataObject obj in signedXml.Signature.ObjectList)
{
tmp.AddObject(obj);
}
tmp.AddReference(new Reference(""));
tmp.ComputeSignature();
XmlTextWriter prettyOut = new XmlTextWriter(System.Console.Out);
prettyOut.Formatting = Formatting.Indented;
Console.WriteLine("Original document");
doc.WriteTo(prettyOut);
Console.WriteLine();
Console.WriteLine();
XmlElement elem = tmp.GetXml();
doc.DocumentElement.AppendChild(elem);
Console.WriteLine("Stage 1 signed");
doc.WriteTo(prettyOut);
Console.WriteLine();
Console.WriteLine();
signedXml.ComputeSignature();
doc.DocumentElement.RemoveChild(elem);
doc.DocumentElement.AppendChild(signedXml.GetXml());
Console.WriteLine("Stage 2 signed");
doc.WriteTo(prettyOut);
}