Publicación técnica
Cómo descifrar datos de tarjetas de crédito, parte I
Una pregunta que surge a menudo es: los datos de pista que obtengo de mi lector de tarjetas ID TECH están cifrados. ¿Cómo los descifro?
La respuesta es: necesitas obtener la clave de sesión adecuada para la transacción y, después, utilizar esa clave para descifrar la carga útil de datos mediante Triple-DES (o AES, según corresponda).
El proceso de descifrado en sí resulta gratamente anticlimático. Lo más probable es que utilices alguna de las múltiples implementaciones de código abierto ya existentes de TDES o AES (no es necesario que implementes tú mismo las rutinas criptográficas básicas), operando en modo CBC (Cipher Block Chaining), con un vector inicial predeterminado de todos los bytes a cero. Suponiendo que dispongas de la clave de descifrado correcta de 16 bytes, el proceso de descifrado es sencillo.
La parte complicada es obtener la clave. Para ello, deberás comprender la norma ANSI X9.24-1, también conocida como DUKPT.
Bienvenido al mundo de DUKPT
Es importante entender que, en los lectores de tarjetas de crédito, cada transacción genera datos que se cifran con una clave diferente. La clave es exclusiva de cada transacción (de ahí el acrónimo DUKPT: Derived Unique Key Per Transaction, clave única derivada por transacción). Ninguna clave se utiliza dos veces. Como consecuencia, los ataques de repetición son prácticamente imposibles.
Para entender cómo funciona DUKPT, hay que conocer un poco el concepto de Key Serial Number (KSN). Lo principal es saber que el KSN es un valor de 10 bytes que cambia en cada transacción, ya que los 21 bits inferiores constituyen un contador.
Estructura del Key Serial Number.
Recuerda: cada transacción de tarjeta cifrada va acompañada de un KSN. El KSN siempre tiene 10 bytes de longitud. Y siempre se envía en claro, ya que el KSN, por sí solo, no revela información sensible (si bien es imprescindible para derivar una clave de sesión).
Cuando un lector de tarjetas se configura para cifrado en fábrica, se le inyecta una clave de 16 bytes y un KSN inicial de 10 bytes. La clave que se inyecta deriva de una clave ultrasecreta (que nunca se inyecta) denominada BDK, o Base Derivation Key (clave base de derivación). (Ten en cuenta que, dado que se pueden derivar muchas claves a partir de una sola BDK, es posible —y de hecho frecuente— inyectar a cientos o incluso miles de lectores de tarjetas claves únicas procedentes de una misma BDK.) El propio proceso de derivación requiere el uso de un KSN. Como el KSN incluye información sobre el número de serie del dispositivo (además de mucha otra información variada de "espacio de nombres"), un hash (o clave) generado a partir de una combinación BDK+KSN será, en esencia, único para ese dispositivo. Es más, la BDK original nunca puede recalcularse a partir del hash (aunque conozcas el KSN), porque hablamos de un hash unidireccional criptográficamente seguro.
Siempre que se produce una transacción, el lector de tarjetas (si admite DUKPT, como hacen prácticamente todos los lectores actuales) genera una clave única a partir del valor actual del KSN y de algo llamado IPEK (Initial PIN Encryption Key). La clave de sesión resultante, de un solo uso, se emplea entonces para cifrar las partes sensibles de los datos de la transacción.
Una vez cifrados, los datos de la transacción no vuelven a descifrarse hasta llegar al destino autorizado, que puede ser el emisor de la tarjeta. La parte receptora (p. ej., el emisor) utilizará su propia copia de tu BDK (junto con el KSN de la transacción) para volver a derivar la clave de sesión de la transacción y recuperar los datos originales (descifrados). Se trata de un proceso denominado simétrico, porque tanto la parte que cifra como la que descifra deben conocer previamente el mismo secreto (la BDK). Se da por supuesto que habrás facilitado de antemano a la parte receptora el "secreto" necesario para que ambos podáis descifrar los mensajes.
La IPEK
El punto de partida para obtener una clave de sesión DUKPT es siempre derivar la IPEK, o clave inicial, algo que solo puedes hacer si conoces la BDK original y el KSN. (Aquí sirve cualquier KSN del dispositivo en cuestión, ya que en este paso vas a poner el contador a cero.)
Para derivar una clave inicial de cifrado de PIN (IPEK), debes hacer lo siguiente:
1. Si tu BDK tiene un tamaño de 16 bytes, amplíala a 24 bytes mediante el llamado método EDE3. Esto significa simplemente: copia los primeros 8 bytes de la clave al final, creando una clave de 24 bytes en la que los primeros y los últimos 8 bytes son iguales.
Si tu clave original (en hexadecimal) tiene este aspecto:
Quieres que acabe teniendo este otro:
2. Enmascara tu KSN inicial de 10 bytes aplicándole un AND con el valor hexadecimal 0xFFFFFFFFFFFFFFE00000. Llamaremos al resultado "KSN enmascarado".
3. Crea un valor de 8 bytes a partir del KSN enmascarado conservando únicamente los primeros 8 bytes (es decir, los de la izquierda) de los 10 bytes del KSN enmascarado. Dicho de otro modo, descarta los dos bytes de la derecha.
4. Utilizando tu BDK ampliada a 24 bytes como clave, cifra con TDES los 8 bytes del KSN enmascarado que obtuviste en el paso 3. Para esto usarás un vector inicial con todos los bytes a cero. (Ten en cuenta que el encadenamiento de bloques cifrados no es relevante aquí, ya que los datos en este caso constan de un solo bloque: 8 bytes.) Conserva el cifrado de 8 bytes que obtengas en este paso, porque será la mitad izquierda de la IPEK de 16 bytes.
5. Para obtener la mitad derecha de la IPEK, primero aplica un XOR a tu BDK original de 16 bytes con el valor hexadecimal 0xC0C0C0C000000000C0C0C0C000000000. (Si utilizas un lenguaje de programación que admita aritmética de enteros grandes, esto puede hacerse en una sola línea de código. Si no, tendrás que aplicar el XOR de forma incremental, parte por parte.)
6. Amplía con EDE3 el valor de 16 bytes obtenido en el paso 5 para obtener una clave de 24 bytes.
7. Utilizando la clave de 24 bytes del paso 6, cifra con TDES los 8 bytes del KSN enmascarado que obtuviste en el paso 3. Esa es ya la mitad derecha de la IPEK.
8. Concatena las mitades izquierda y derecha de la IPEK. Ya tienes la IPEK final de 16 bytes.
Si vas a implementar esto tú mismo en código, prueba a generar una IPEK a partir de una clave de prueba con valor 0123456789ABCDEFFEDCBA9876543210 y un KSN de 62994900000000000001. La IPEK resultante debería ser B5610650EBC24CA3CACDD08DDAFE8CE3.
Gestión de claves frente a algoritmos de cifrado
Por cierto, te habrás dado cuenta de que en DUKPT se utiliza mucho Triple-DES (TDES). En ningún momento se utiliza AES (aunque tu lector de tarjetas esté configurado para usar AES en el cifrado). La norma X9.24 exige TDES, y en ocasiones DES simple. Que te quede claro que el proceso de derivación de claves DUKPT es totalmente independiente del proceso de cifrado/descifrado de los datos de la transacción. En un caso, estás derivando una clave. En el otro, estás utilizando esa clave para realizar la codificación TDES o AES. Ninguna rutina de cifrado sabe ni le importa de dónde procede tu clave, ni qué algoritmos se usaron para construirla; lo único que importa es que la propia clave funcione. Así que, aunque los datos que necesitas desbloquear pueden haberse cifrado con AES, la clave que utilizas para desbloquearlos se derivará mediante DUKPT, que (internamente) utiliza TDES.
¿Dónde está el código?
En la parte II de este artículo entraremos en bastante detalle sobre cómo utilizar una IPEK más un KSN para derivar una clave de sesión DUKPT real. Veremos código fuente real para que puedas hacerlo todo por ti mismo. Si no puedes esperar a la próxima entrega para ver el código fuente, echa un vistazo a nuestra popular Herramienta de cifrado/descifrado, que contiene una implementación en JavaScript totalmente funcional de los algoritmos DUKPT que trataré en la parte II (junto con implementaciones de código abierto de TDES y AES). Puedes utilizar la herramienta de cifrado/descifrado para derivar claves DUKPT (en sus 3 variantes: PIN, Data y MAC), cifrar o descifrar datos (con TDES o AES), generar diversos tipos de hashes y mucho más. Y lo mejor de todo: como la herramienta es simplemente una página web, funcionará en cualquier navegador (en cualquier plataforma) que admita JavaScript.
¿Quieres derivar una clave de sesión DUKPT de variante de datos a partir de un KSN y un IPEK? Continúa con la Parte II de este artículo.
