I'm trying to sign an XML by passing the reference tag, id, XML, and certificate.
In a certain situation it does not work, but I never know what the situation is, it's a bit random.
And now, even though I'm changing reference.uri
to put or not by an underline, it's not going through the ComputeSignature()
method.
Could you help me?
public string Assinar(string XMLString, string RefUri, X509Certificate2 _X509Cert, object id, bool assinarTagSignature = true)
{
string xmlResultado = string.Empty;
try
{
string x;
x = _X509Cert.GetKeyAlgorithm().ToString();
//Create a new XML document.
XmlDocument doc = new XmlDocument();
//Format the document to ignore white spaces.
doc.PreserveWhitespace = false;
//Load the passed XML file using it's name.
try
{
try
{
doc.LoadXml(XMLString);
}
catch (Exception ex)
{
sResultado = XMLString;
throw new Exception("erro ao ler");
}
//Verifica se a tag a ser assinada existe é única
int qtdeRefUri = doc.GetElementsByTagName(RefUri).Count;
if (qtdeRefUri == 0)
{
//a URI indicada não existe
iResultado = 4;
sResultado = "A tag de assinatura " + RefUri.Trim() + " inexiste";
}
//Exsiste mais de uma tag a ser assinada
else
{
if (qtdeRefUri > 1)
{
//Existe mais de uma URI indicada
iResultado = 5;
sResultado = "A tag de assinatura " + RefUri.Trim() + " não é unica";
}
else
{
try
{
//Create a SignedXml object.
SignedXml signedXml = new SignedXml(doc);
//Add the key to the SignedXml document
signedXml.SigningKey = _X509Cert.PrivateKey;
//Create a reference to be signed
Reference reference = new Reference();
//pega o uri que deve ser assinada
XmlAttributeCollection tagUri = doc.GetElementsByTagName(RefUri).Item(0).Attributes;
if (id.ToString() != "0")
foreach (XmlAttribute _atributo in tagUri)
{
if (_atributo.Name == "Id")
{
reference.Uri = "#" + _atributo.InnerText;
//reference.Uri = _atributo.InnerText;
}
}
else
reference.Uri = "";
/*
foreach (XmlAttribute _atributo in tagUri)
{
if (_atributo.Name == "Id")
{
reference.Uri = "#" + _atributo.InnerText;
}
}
*/
//Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
XmlDsigC14NTransform c14 = new XmlDsigC14NTransform();
reference.AddTransform(c14);
//Add the reference to the SignedXml object.
signedXml.AddReference(reference);
//Create a new KeyInfo object
KeyInfo keyInfo = new KeyInfo();
//Load the certificate into a KeyInfoX509Data object
//and add it to the KeyInfo object.
keyInfo.AddClause(new KeyInfoX509Data(_X509Cert));
//Add the KeyInfo object to the SignedXml object.
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
//Get the XML representation of the signature and save
//it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
if (assinarTagSignature)
xmlDigitalSignature.SetAttribute("Id", "Ass_" + id.ToString());
//Append the element to the XML document.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
XmlDocument XMLDoc = new XmlDocument();
XMLDoc.PreserveWhitespace = false;
XMLDoc = doc;
xmlResultado = XMLDoc.InnerXml;
}
catch (Exception caught)
{
iResultado = 7;
sResultado = "Erro: Ao assinar o documento - " + caught.Message;
}
}
}
}
catch (Exception caught)
{
iResultado = 3;
sResultado = "XML mal formado - " + caught.Message + " " + XMLString;
}
}
catch (Exception caught)
{
iResultado = 1;
sResultado = sResultado = "Problemas na seleção do certificado digital: " + caught.Message;
}
sResultado = "Arquivo Assinado Com Sucesso";
return xmlResultado;
}