Buscar en este blog

Mostrando entradas con la etiqueta Cómo se firma el DTE. Mostrar todas las entradas
Mostrando entradas con la etiqueta Cómo se firma el DTE. Mostrar todas las entradas

viernes, 24 de mayo de 2013

Cómo firmar el DTE

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.