Skip to content

Instantly share code, notes, and snippets.

@ryanpadilha
Created March 26, 2016 01:28
Show Gist options
  • Save ryanpadilha/f5f32b17fb94bc109022 to your computer and use it in GitHub Desktop.
Save ryanpadilha/f5f32b17fb94bc109022 to your computer and use it in GitHub Desktop.
Assinatura Digital XML x509 v3
// declarando variaveis e enumerador necessarios
enum ResultadoAssinatura
{
XMLAssinadoSucesso,
CertificadoDigitalInexistente,
TagAssinaturaNaoExiste,
TagAssinaturaNaoUnica,
ErroAssinarDocumento,
XMLMalFormado,
ProblemaAcessoCertificadoDigital
}
private ResultadoAssinatura Resultado;
private string Mensagem;
public string AssinarXML(string pArquivoXML, string pUri, X509Certificate2 pCertificado)
{
StreamReader sr = File.OpenText(pArquivoXML);
string XML = sr.ReadToEnd();
sr.Close();
// parametros de retorno
string XMLAssinado = String.Empty;
this.Resultado = ResultadoAssinatura.XMLAssinadoSucesso;
this.Mensagem = "Assinatura realizada com sucesso.";
try
{
// verificando existencia de certificado utilizado na assinatura
string subject = String.Empty;
if (pCertificado != null)
subject = pCertificado.Subject.ToString();
X509Certificate2 x509Certificate = new X509Certificate2();
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection collection1 = (X509Certificate2Collection)collection.Find(X509FindType.FindBySubjectDistinguishedName, subject, false);
if (collection1.Count == 0)
{
this.Resultado = ResultadoAssinatura.CertificadoDigitalInexistente;
this.Mensagem = "Problemas no certificado digital.";
}
else
{
XmlDocument documento = new XmlDocument();
documento.PreserveWhitespace = false;
try
{
// verificando elemento de referencia
documento.LoadXml(XML);
int qtdeRefUri = documento.GetElementsByTagName(pUri).Count;
if (qtdeRefUri == 0)
{
this.Resultado = ResultadoAssinatura.TagAssinaturaNaoExiste;
this.Mensagem = "A tag de assinatura " + pUri.Trim() + " não existe.";
}
else
{
if (qtdeRefUri > 1)
{
this.Resultado = ResultadoAssinatura.TagAssinaturaNaoUnica;
this.Mensagem = "A tag de assinatura " + pUri.Trim() + " não é unica.";
}
else
{
try
{
// selecionando certificado digital baseado no subject
x509Certificate = collection1[0];
SignedXml docXML = new SignedXml(documento);
docXML.SigningKey = x509Certificate.PrivateKey;
Reference reference = new Reference();
XmlAttributeCollection uri = documento.GetElementsByTagName(pUri).Item(0).Attributes;
foreach (XmlAttribute atributo in uri)
{
if (atributo.Name == "Id")
reference.Uri = "#" + atributo.InnerText;
}
// adicionando EnvelopedSignatureTransform a referencia
XmlDsigEnvelopedSignatureTransform envelopedSigntature = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(envelopedSigntature);
XmlDsigC14NTransform c14Transform = new XmlDsigC14NTransform();
reference.AddTransform(c14Transform);
docXML.AddReference(reference);
// carrega o certificado em KeyInfoX509Data para adicionar a KeyInfo
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(x509Certificate));
docXML.KeyInfo = keyInfo;
docXML.ComputeSignature();
// recuperando a representacao do XML assinado
XmlElement xmlDigitalSignature = docXML.GetXml();
documento.DocumentElement.AppendChild(documento.ImportNode(xmlDigitalSignature, true));
XMLAssinado = documento.OuterXml;
}
catch (Exception caught)
{
this.Resultado = ResultadoAssinatura.ErroAssinarDocumento;
this.Mensagem = "Erro ao assinar o documento - " + caught.Message;
}
}
}
}
catch (Exception caught)
{
this.Resultado = ResultadoAssinatura.XMLMalFormado;
this.Mensagem = "XML mal formado - " + caught.Message;
}
}
}
catch (Exception caught)
{
this.Resultado = ResultadoAssinatura.ProblemaAcessoCertificadoDigital;
this.Mensagem = "Problema ao acessar o certificado digital - " + caught.Message;
}
return XMLAssinado;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment