Cómo se firma el DTE
Bueno en este tema existen muchos que pueden dar
una opinión acerca de cómo realizar esta tarea, sin embargo la experiencia me
ha demostrado que el problema no es firmar el documento sino más bien que es lo
que debemos firmar. Muchas personas me dicen que firman sus documentos DTE pero
al momento de enviarlos al SII este les regresa que la firma es inválida.
Expondré aquí la forma que utilizo personalmente para realizar el proceso, sin
perjuicio que existan otros desarrolladores que utilicen una forma mas elegante.
Consideraciones generales
Una de las primeras cosas que
realizo al momento de intentar firmar el documento DTE es ordenar la
información a firmar. Los desarrolladores con más experiencia en este tema
saben que al construir un documento XML este no es necesariamente el mismo
cuando uno lo visualiza en otros visualizadores de documentos XML. Bueno
regresando a lo nuestro, primero ordenemos el DTE
Identación
Si Ud. Cuenta con un documento
DTE con estas características lo primero que debería hacer es quitar la
identación del documento. Esto tiene una razón, puesto que el CAF entregado por
el SII no trae identación es preferible dejar todo el documento alineado según el
CAF. Entonces al momento de calcular la firma sobre el CAF no generará errores
de timbre. Esta es mi opinión, no exenta de comentarios y observaciones.
Deje el documento DTE de esta forma.
CAF
Una vez ordenado el documento
DTE, es necesario agregar el CAF al documento, para esto es necesario tomar el
nodo CAF desde el archivo de autorización de folios del SII. Cuando digo tomar,
es rescatar el nodo sin realizar ninguna modificación o identación. El nodo CAF
debe ser insertado tal cual en el documento DTE. Si se modifica de alguna forma
el cálculo del timbre fallará.
Entonces segun esto el DTE debería quedar como sigue:
Posterior a esto se encuentra la generación del timbre del TED, cuya información se encuentra disponible en la sección Ejemplo Timbre Electrónico del DTE . Cuando genere el timbre del TED su DTE debería tener esta forma:
Aplicar Firma al DTE
Bueno ya
tiene preparado su DTE para ser firmado. Ahora debemos aplicar la siguiente
rutina de firma al DTE expuesto. Antes debo señalar que al momento de abrir el
documento XML en .Net utilice la propiedad PreserveWhiteSpace = true del objeto
XmlDocument. Esto logra abrir el DTE sin ordenar los nodos o identarlo. Si no
lo hace de esta forma el timbre que calculo se invalidará.
Una vez abierto el DTE (xml) puede aplicar esta rutina para su firmado:
#region FIRMA DTE public static void firmarDocumentoXml(ref XmlDocument xmldocument, X509Certificate2 certificado, string referenciaUri ) { //// //// Cree el objeto SignedXml donde xmldocument //// representa el documento DTE preparado para //// ser firmado. Recuerde que debe ser abierto //// con la propiedad PreserveWhiteSpace = true SignedXml signedXml = new SignedXml(xmldocument); //// //// Agregue la clave privada al objeto signedXml signedXml.SigningKey = certificado.PrivateKey; //// //// Recupere el objeto signature desde signedXml Signature XMLSignature = signedXml.Signature; //// //// Cree la refrerencia al documento DTE //// recuerde que la referencia tiene el //// formato '#reference' //// ejemplo '#DTE001' Reference reference = new Reference(); reference.Uri = referenciaUri; //// //// Agregue la referencia al objeto signature XMLSignature.SignedInfo.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue((RSA)certificado.PrivateKey)); //// //// Agregar información del certificado x509 keyInfo.AddClause(new KeyInfoX509Data(certificado)); XMLSignature.KeyInfo = keyInfo; //// //// Calcule la firma y recupere la representacion //// de la firma en un objeto xmlElement signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); //// //// Inserte la firma en el documento DTE xmldocument.DocumentElement.AppendChild(xmldocument.ImportNode(xmlDigitalSignature, true)); } #endregion
Para ser honesto esta rutina es capaz de firmar el DTE y El SETDTE solo se debe pasar la referencia adecuada para indicar que nodo debe firmar.
Bueno espero que esta breve rutina les permita avanzar en sus proyectos. Como siempre los invito a dejar un comentario acerca de como mejorar estas rutinas.