Llama Gratis 800 788 0195

¿Qué es el sello?

El sello es el resultado de la firma de la cadena original obtenida del Comprobante Fiscal Digital por Internet en base64. El propósito del sello es emitir comprobantes y acreditar al creador del comprobante fiscal digital con autenticidad, integridad, verificables y no repudiables por el emisor. Para poder generar el sello es necesario tener el resultado de la cadena original que es obtenido del xml del comprobante a sellar, también es necesario los certificados de sello digital (.cer y .key) convertidos a “pem”.

El sello contiene la información del emisor e información del comprobante codificada, que si dicho comprobante por algún motivo sufre cambios y no se vuelve a generar un sello nuevo, nos arrojará error al tratar de realizar el timbrado.

¿Qué se necesita para generar el sello?

Para poder generar el sello es necesario contar con los siguientes elementos:

  • Cadena Original del XML a sellar.
  • Certificado de Sello Digital en formato PEM y su correspondiente llave privada tambien en formato PEM.
  • Algoritmos de criptografía para la generación de la Digestión o Hash.
  • Utilerias o funciones de criptografia (por  ej. OpenSSL)

¿Qué es la cadena original?

Se entiende como cadena original, a la secuencia de datos formada con la información contenida dentro del comprobante, establecida en el Rubro I.A. del Anexo 20 Estándar.

Es importante mencionar que la secuencia de formación siempre se registra en el órdenes que se expresa en el apartado correspondiente a cada uno de los comprobantes fiscales, complementos y del timbre fiscal digital del SAT, tomando en cuenta las reglas generales que se muestran a continuación:

¿Reglas generales para generar la cadena original?

  • Al inicio y al finalizar la cadena original se encuentra marcado mediante una secuencia de caracteres || (doble pleca).
  • Se debe de expresar únicamente la información del dato sin expresar el atributo al que hace referencia. Es decir, si el valor de un campo es “A” y el nombre del campo es “Concepto”, sólo se expresa |A| y nunca |Concepto A|.
  • Cada dato individual se debe separar de su dato subsiguiente, en caso de existir, mediante un carácter | (pleca sencilla).
  • Los espacios en blanco que se presenten dentro de la cadena original son tratados de la siguiente manera:
    • Se deben de reemplazar todos los tabuladores, retornos de carro y saltos de línea por el carácter espacio (ASCII 32).
    • Acto seguido se elimina cualquier espacio al principio y al final de cada separador | (pleca).
    • Finalmente, toda secuencia de caracteres en blanco se sustituye por un único carácter espacio (ASCII 32).
  • Los datos opcionales no expresados, no aparecen en la cadena original y no tienen delimitador alguno.
  •  Toda la cadena original se expresa en el formato de codificación UTF-8.
  • El nodo o nodos adicionales se integra a la cadena original como se indica en la secuencia de formación en su numeral 10, respetando la secuencia de formación y número de orden del ComplementoConcepto.
  • El nodo o nodos adicionales se integra al final de la cadena original respetando la secuencia de la formación para cada complemento y número de orden del Complemento

¿Cómo generar la cadena original?

Para poder extraer la cadena original de un XML (CFDI) es necesario hacer uso de un lenguaje de transformación de documentos como lo es el XSLT, en este caso nos permite obtener/trasnsformar la información contenida en el XML a una cadena de texto, con la secuencia de datos y lineamientos que la plantilla de Secuencia de CadenaOriginal (XSLT) del SAT especifica.

Los elementos que debemos de considerar para la extracción de la cadena original son los siguientes:

Para poder utilizar la herramienta XSLT, solo es necesario copiar y pegar el contenido del XML, en el recuadro donde lo indique y en el segundo cuadro se estará agregando el contenido del XSLT es decir secuencia de la cadena original.

Es importante mencionar que la cadena original se debe de extraer la misma cantidad de veces que dicho comprobante de CFDI sufra algún cambio.

El resultado de la extracción de la cadena original es el siguiente, el cual estaremos guardando en un archivo, en este paso para efecto del ejemplo le pondremos como nombre “Cadena_original.txt”:

||3.3|2018-11-27T12:37:40|01|30001000000300023708|6260.00|MXN|1|7261.60|I|PUE|06300|AAA010101AAA|SENTIENT SA DE CV|601|IAD121214B34|IT SW Development Solutions de Mexico S de RL de CV|P01|10122100|6|M74|Kilo|prueba Catalogos Nuevos|1000.00|6000.00|6000.00|002|Tasa|0.160000|960.00|24111500|1|KGM|kg|traslucida 90x90 cm. cal. 200|22.00|22.00|22.00|002|Tasa|0.160000|3.52|13101712|10|KGM|KG|POLIETILENO DE BAJA DENSIDAD|23.80|238.00|238.00|002|Tasa|0.160000|38.08|002|Tasa|0.160000|1001.60|1001.60||

¿Cómo generar el sello?

Para la generación del sello digital de los comprobantes CFDI’s tal como lo especifica el anexo 20 en el inciso I Sección B. Los algoritmos a utilizar son los siguientes:

  • SHA-2 o SHA-256, para el sellado del Comprobante Fiscal Digital a través de Internet.
  • SHA-1, para sellar el Comprobante Fiscal Digital a través de Internet que ampara Retenciones e Información de Pagos.

A continuación les mostraremos una serie de pasos que necesitamos hacer primero para poder obtener la digestión, utilizando los comandos de OpenSSL.

Paso 1.- Contar con el certificado convertido en formato PEM.

openssl x509 -in 'CSD01_AAA010101AAA.cer' -inform DER -out 'CSD01_AAA010101AAA.cer.pem' -outform PEM

Paso 2.-Contar con la llave convertida a PEM.

openssl pkcs8 -inform DER -in 'CSD01_AAA010101AAA.key' -passin pass:12345678a -out 'CSD01_AAA010101AAA.key.pem'

Paso 3.- Generar la Digestión o Hash

openssl dgst -sha256 -sign 'CSD01_AAA010101AAA.key.pem' -out 'digest.txt' 'cadena_original.txt'

Paso 4.- Creación del archivo PEM de la llave privada

openssl enc -in 'digest.txt' -out 'sello.txt' -base64 -A -K 'CSD01_AAA010101AAA.key.pem'

Ejemplo de la Generación del Sello

Sello="Vve+KIMdhPjSiPoA+oFPOI1+DHhbIZpAfjHDjdvuDpN9ga4g76DS90JDlY1mwXAOSOwTlA3YUSwFSt23piTUz9fd+e79xhEzLis6Tiarir0EwADu5tHtZezVMzkD4q4hf+qnpFwx9/F8pUd8eU0T6+fvchQyDE8JhTsTAVdKeD7UGjEwr8lbQ0QVVqXf0i3LWLkkrw0IGt4+NKMgp2WcmDmMkcf+fLYBFJmtrb2KQEgG6nc3IG5Bjik2t34BtYrGWfH9FQR9weBitJRMLfq4Lsmv++j9HlehnCdTlHAzEHpUCvSRw8HPQhhMNBg3zYMAWgM9FpPaUuTKFlkjHJbT4w=="