miércoles, 21 de noviembre de 2007

Facturación Electrónica

Hace unas semanas me puse a investigar sobre la Facturación Electrónica, la cual en nuestro país México tiene algunos años que se inicio este proceso de Facturación y todo lo referente a ella se podrá encontrar aquí. Pero en esta ocación no voy hablar mucho acerca del proceso y como hay que seguirlo desde el inicio, no, esta ocación solo hablaremos de como realizar un buen sellado de nuestra cadadena original. Para más información visitar esta dirección.

Bueno iniciamos, una de las maneras de poder llevar acabo la firma de la cadena original es utilizando las herramientas proporcionadas por OpenSSL, aunque tiene sus problemitas pero en fin acontinuación resumó los pasos que se tienen que llaver acabo para ejecutar la firma de la cadena original.

1.- Obtener la cadena original, en este caso utilizaremos la cadena original utilizada en un ejemplo propuesto por el SAT.

Cadena Original:

||A|1|2005-09-02T16:30:00|1|ISP900909Q88|Industrias del Sur Poniente, S.A. de C.V.|Alvaro Obregón|37|3|Col. Roma Norte|México|Cuauhtémoc|Distrito Federal|México|06700|Pino Suarez|23|Centro|Monterrey|Monterrey|Nuevo Léon|México|95460|CAUR390312S87|Rosa María Calderón Uriegas|Topochico|52|Jardines del Valle|Monterrey|Monterrey|Nuevo León|México|95465|10|Caja|Vasos decorados|20|200|1|pieza|Charola metálica|150|150|IVA|52.5||


2.- Digestión de la cadena original en formato MD5.

Cabe mencionar que la cadena original se debe encontrar codificado en UTF-8 de lo contrario jamas obtendremos el valor esperado, el cual es:

8aa2b617944427353697e694a2e35a07

3.- Sellar (Firmar) la digestión de la cadena original.

4.- El valor obtenido codificarlo a Base64.

Estos son los pasos para poder obtener la Firma de los datos que se plasmaran en la Factura Electrónica para su validez.

Investigando me encontre con paginas donde te decian como utilizar el sw openssl para firmar tu cadena original y aparecia lo siguiente:

Digestión de la cadena original:

windows

OpenSSL> dgst -md5 cadena.txt

linux

$>openssl dgst -md5 cadena.txt

Este proceso es correcto solo si el archivo de texto se encuentra codificado en UTF-8, lo cual debemos revisar ya que al guardar un archivo de texto la codificación default que toma el archivo es ANSI.

Nota: Dentro del archivo cadena.txt debemos colocar la cadena original de ejemplo en una sola línea de texto.

Obtenida la digestión y verificando que el resultado es:

8aa2b617944427353697e694a2e35a07

procedemos a colocar este resultado en un archivo de texto.

El siguiente paso es firmar la digestión de la cadena original y en un solo paso codificarla en base64 con salida a un archivo en la ruta especificada.

windows

OpenSSL>dgst -sign AAA01010AAA.pem digestioncadena.txt | enc -base64 -A > sello.txt

linux

$>openssl dgst -sign AAA010101AAA.pem digestioncadena.txt | openssl enc -base64 -A > sello.txt

Pues bien así obtenemos nuestra firma de la cadena original.

Nota: En algunos lugares encontraras las siguientes líneas
OpenSSL>dgst -md5 -sign AAA01010AAA.pem cadenaoriginal.txt | enc -base64 -A > sello.txt

No pueder realizar el paso de digestión y selledo de la cadena original en una solo línea por lo cual esta línea solo nos dice que se ocupara el metodo hash de encriptación MD5 para Sellar la cadena original utilizando la Clave privada AAA010101AAA.pem. Entonces sella la cadena original y no la digestión de la cadena original como se pensaria.

Debemos revisar bien todos estos pasos antes de realizar la firma de la cadena original.

Para finalizar el certificado y la clave privada utilizado para este ejemplo lo encuentran en la siguiente ruta Certificado y Key

Tanto la clave como el certificado se encuentran en formato DER y openssl lo utiliza en formato PEM, la conversión de la clave privada es la siguiente:

windows:

OpenSSL>pkcs8 -inform DER -in AAA010101AAA.key -out AAA010101AAA.pem

linux:

$>openssl pkcs8 -inform DER -in AAA010101AAA.key -out AAA010101AAA.pem

Listo tenemos nuestro clave privada en formato PEM.

Windows no cuenta con una intalación de OpenSSL predeterminada por lo cual les dejo este enlace para su descarga.

Si alguien quiere realizar este proceso sin utilizar el sw OpenSSL les recomiendo que visiten. BouncyCastle ahi encontraran una libreria muy completa para manipulación de certificados, digestión y sellado de información y manipulación de claves, se encuentra en versión tanto para Java como C#.

11 comentarios:

Anónimo dijo...

Algo curioso en base a lo que explicas, es que no obtenemos el mismo resultado al ejecutar lo siguiente:

openssl dgst -md5 -sign AAA010101AAA_0408021316S.key.pem cadena_original.txt | openssl enc -base64 -A > base64.txt

Qué es generar todo de un jalón y que para el caso de SAT, si genera el certificado tal como se muestra en el sitio de SAT..

Y usando este procedimiento que es basicamente primero generar el md5 para la cadena original y luego hacer el firmado del documento, si comparamos los resultados son muy diferentes

openssl dgst -md5 cadena_original.txt

openssl dgst -sign AAA010101AAA_0408021316S.key.pem md5.txt

Entonces esto puede causar confusión.

Anónimo dijo...

Seguí todos tus pasos y puse lo que hice en foros del web, no me salio a fin de cuentas a pesar de que si fue simple el proceso, te paso el link para ver si lo puedes checar.

http://www.forosdelweb.com/f18/facturacion-electronica-mexico-638882/

Rulo dijo...

Ahorita estoy muy ocupado con el trabajo pase de rapido a revisar tu codigo o el codigo que se encuentra en foros de web y de lo que me doy cuenta es de que la generación de tu archivo XML no sigue las especificaciones del esquema CFD_2 del SAT, espero tenerr un poko mas de tiempo y poder ayudarte posteriormente.

Beto dijo...

Hola, estan intersantes tu posts. Me gustaria saber si has logrado una implementacion para generar el sello digital usando C# con alguna biblioteca externa. Gracias de antemano.

Rulo dijo...

Te comento que si he realizado la implementación de la firma digital en c# y he utilizado una libreria llamada BouncyCastle

Anónimo dijo...

Tengo el codigo con bouncecastle pero pus no jala ja ja ja toncs no se tiene ke generar con openssl es mi duda y a parte combinar el cer kon el md5 y key, sabe ja ja ja salu2, buen blog

Rulo dijo...

hace un rato que no he tenido el tiempo de contestar sus dudas sobre la facturación electrónica y la vdd lo que sucedió que perdí un poco el interés en el proyecto a raíz de que muy poca gente le interesaba mi idea y junto con el trabajo me fui imposible continuar con el proyecto por ello les comentó sobre el siguiente link que realicé algunos meses atras subi mi código hecho todo en java para que puedan revisarlo y hacer los cambios que crean convenientes, el código le hace falta una función y para mi gustó la más importante y poder evitar el pasó de .key a .pem la clave privada, esto por la contraseña que contiene esta, una de las soluciones que encontre después de intentar de todo para poder leer un archivo DER con java fue que cuando lo debía hacer era primero convertir la contraseña a una cadena MD5 y después enviarla como clave secreta para poder leer el archivo DER y creanme que hay muy información sobre este tema, algo que leí o en donde base gran parte de mi investigación fue el libro Java Security muy recomendable, sin más les dejo el link para que visiten el proyecto cualquier comentario espero porder ayudarlos. gracias por sus coments.
http://code.google.com/p/cx-faktura/

Guru Sistemas dijo...

Hay alguna manera de que publiques el codigo que tienes con c#.

Gracias

Rulo dijo...

ok mira hace mucho que perdí ese código; pero si revisas el código de java que la vdd es muy simalar c# podrás orientarte, si tienes problemas con lo lenguajes podemos de alguna ponernos en contacto para poder revisarlo y ayudarte a migrar tu aplicación ha c#

Anónimo dijo...

He tratado de sacar lo del md5 con open ssl de la cadena original y no sale 8a.... sale 91b1 y pues que onda en cambio con vb.net he obtenido el resultado del 82... pero en fin. al moemnto de la dgst me dice no such file or directory y eso ke está en el mismo folder. :P ja ja ja bueno seguiré con esto y pues roberto iwal deja tu correo a ver ke podemos hacer juntos.

Saludos

Rulo dijo...

para todos los chicos que tiene dudas mi correo es rene.trejo@gmail.com