Created
March 26, 2016 01:28
-
-
Save ryanpadilha/f5f32b17fb94bc109022 to your computer and use it in GitHub Desktop.
Assinatura Digital XML x509 v3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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