ID TECH
Contatto
Tutti gli articoli tecnici

Post tecnico

Come decrittare i dati delle carte di credito, Parte II

I clienti chiedono spesso: Come posso decrittare i dati provenienti dal mio lettore di carte di credito ID TECH?

La risposta: è necessario conoscere l'algoritmo utilizzato per cifrare i dati e la chiave impiegata. A quel punto sarà possibile decrittare i dati tramite tale chiave.

Oggigiorno, quasi tutti i dati delle carte di credito vengono cifrati mediante una chiave monouso, ottenuta attraverso uno schema di gestione delle chiavi denominato DUKPT (acronimo di Derived Unique Key Per Transaction). È importante comprendere che nel sistema DUKPT ogni transazione dispone di una propria chiave. Tale chiave non può essere riutilizzata per nessun'altra transazione; di conseguenza, gli attacchi di tipo replay sono impossibili.

La domanda è: come si può derivare una chiave DUKPT in grado di sbloccare una determinata transazione? La risposta è: in linea generale, è necessario disporre del Key Serial Number (KSN) relativo alla transazione, oltre che di un valore speciale denominato IPEK, ovvero la chiave iniziale iniettata nel lettore di carte di credito. L'IPEK, a sua volta, è derivata da una chiave segreta (che non viene mai iniettata in un lettore di carte) chiamata BDK (Base Derivation Key). A differenza della BDK, l'IPEK è univoca per ciascun dispositivo fisico. (Una singola BDK può essere la sorgente di molte IPEK univoche.) Se non si conosce l'IPEK del proprio dispositivo (e non vi è motivo per cui si dovrebbe conoscerla, poiché l'IPEK non viene mai annotata da nessuna parte), è possibile derivarla da un KSN e da una Base Derivation Key, utilizzando la tecnica descritta nella Parte I di questo articolo.

La derivazione di una chiave di sessione (talvolta chiamata chiave operativa, o semplicemente "chiave dati") si articola in realtà in un processo composto da 3 fasi, descritte di seguito.

1. Utilizzare la BDK e il KSN per derivare l'IPEK. (Vedere Parte I di questo articolo per i dettagli su come eseguire questa operazione.)

2. Utilizzare l'algoritmo di derivazione delle chiavi ANSI X9.24 (DUKPT) per ricavare una chiave base, o "chiave derivata" iniziale, dal KSN e dall'IPEK.

3. Convertire la chiave derivata ottenuta nel passaggio 2 nella variante desiderata: Data Key, PIN Key o MAC Key. (Si noti che, sebbene la maggior parte dei lettori di carte di credito sia configurata per utilizzare la variante Data come chiave di sessione per le transazioni, alcuni dispositivi sono invece configurati per utilizzare la variante PIN.)

Vediamo ora cosa comporta l'ottenimento della "chiave derivata" (passaggio 2), che rappresenta di gran lunga la fase più laboriosa dell'intero processo in tre fasi. Una volta ottenuta la chiave derivata, illustreremo come trasformarla nella variante Data, PIN o MAC, operazione relativamente semplice.

Di seguito verrà utilizzato un certo quantitativo di pseudocodice, ma è possibile trovare il codice sorgente completo e funzionante (in JavaScript) per tutti i passaggi descritti nel nostro popolare Strumento di Cifratura/Decifratura. (Provalo subito, se non l'hai ancora fatto. Si tratta di una pagina web autonoma che funziona su qualsiasi browser moderno.)

Derivazione di una chiave

Per ricavare la chiave base dalla quale è possibile creare una variante Data, PIN o MAC, è necessario disporre di un KSN di transazione e di un IPEK. Una volta ottenuti questi elementi (come indicato in Parte I di questa serie), procedere come segue:

1. Estrarre gli 8 byte inferiori (più a destra) del KSN a 10 byte. Scartare i due byte superiori.

2. Creare una variabile BaseKSN per contenere una versione mascherata del KSN a 8 byte. Ottenere la versione mascherata applicando l'operazione AND logico tra il KSN a 8 byte del passaggio 1 e il valore esadecimale 0xFFFFFFFFFFE00000.

3. Estrarre i bit del contatore dal KSN originale a 10 byte (non mascherato!) applicando l'operazione AND logico tra i tre byte inferiori e il valore 0x1FFFFF. (Si ricorda che i 21 bit inferiori di un KSN costituiscono il contatore di transazione.) Questo valore verrà memorizzato in una variabile denominata (naturalmente) counter.

4. Copiare il proprio IPEK di 16 byte in una variabile denominata curKey.

5. A questo punto è necessario impostare un ciclo. A ogni iterazione, si esaminano i bit del counter (partendo dal bit più significativo, ovvero il 21° bit; alla seconda iterazione si controlla il 20° bit; poi il 19°; e così via). Ogni volta che si individua un bit attivo, lo si applica tramite OR al BaseKSN, quindi si richiama generateKey() per aggiornare curKey. Il BaseKSN accumula bit a ogni iterazione del ciclo, mentre il valore di curKey si aggiorna in corrispondenza di ogni bit del counter trovato attivo.

Cosa fa generateKey() ? Ottima domanda! Se il linguaggio di programmazione utilizzato supporta la matematica con BigInteger, il codice avrà un aspetto simile al seguente:

Bene. Come si può osservare, la chiave di 16 byte viene mascherata e poi utilizzata per cifrare il valore ksn di 8 byte, ottenendo così la metà sinistra (i primi 8 byte) di una nuova chiave. La metà destra della nuova chiave è un codice cifrato generato dallo stesso ksn, ma utilizzando una chiave non mascherata.

Infine, è necessario conoscere come appare encryptRegister() . Eccola:

Si noti che il Cipher Block Chaining è in realtà privo di significato in questo contesto, poiché stiamo cifrando un valore di 8 byte (un singolo blocco di dati). Non c'è nulla da "concatenare". È incluso nel codice semplicemente perché la routine di cifratura richiede un parametro che indica se abilitare o meno il chaining.

Si noti inoltre che per eseguire la cifratura viene utilizzata una chiave di 8 byte. TDES si comporta come un singolo DES quando la chiave è lunga solo 8 byte. Questo perché una chiave di 8 byte, nel contesto del triple DES, produrrebbe un ciclo cifra/decifra/cifra equivalente a una singola operazione di cifratura.

In termini semplici, la routine utilizza gli 8 byte superiori di una chiave a 16 byte per cifrare un valore speciale ottenuto tramite l'operazione XOR tra gli 8 byte inferiori della chiave e il KSN (di 8 byte). Il risultato è un hash unidirezionale del KSN.

Mettendo tutto insieme, il ciclo descritto nel Passaggio 5 produce un valore curKey che diventa la chiave base da cui è possibile derivare le varianti Data, PIN o MAC. (Il ciclo del Passaggio 5 è, o dovrebbe essere, parte di una funzione che restituisce curKey, ovvero la chiave base.)

È giunto il momento di esaminare più in dettaglio le tre opzioni di "variante di chiave".

Creazione delle varianti di chiave Data, PIN e MAC

ANSI X9.24 consente a una chiave DUKPT di assumere una delle tre forme finali, denominate varianti: MAC, PIN e Data. Rimandiamo qualsiasi discussione sull'utilizzo di questi tipi di chiave per concentrarci invece su come vengono create.

Il punto di partenza per qualsiasi variante è una chiave base DUKPT (la chiave derivata che abbiamo chiamato curKey nel Passaggio 5 descritto sopra). Per ottenere la variante MAC, è sufficiente eseguire un'operazione XOR tra la chiave base (la "chiave derivata") e una costante speciale:

La variante PIN viene creata in modo analogo, ma utilizzando una costante diversa:

La variante Data richiede un'ulteriore costante:

Per le varianti MAC e PIN, l'operazione XOR costituisce il passaggio finale nella creazione della session key corrispondente. Per la variante Data, è prassi comune eseguire un ulteriore passaggio, che prevede un hash unidirezionale (per escludere qualsiasi possibilità che qualcuno possa ricavare a ritroso una chiave Data in una chiave MAC). In pseudocodice:

In sintesi: per prima cosa, ottenere una versione a 24 byte della chiave derivata utilizzando il metodo di espansione EDE3. (Questo significa semplicemente copiare i primi 8 byte di una chiave a 16 byte in coda alla chiave stessa, creando così una chiave a 24 byte in cui i primi e gli ultimi 8 byte sono identici.) Utilizzare tale chiave per cifrare con TDES i primi 8 byte della chiave derivata a 16 byte, ottenendo così un cifrario a 8 byte, che costituisce la metà sinistra della chiave dati finale. Per creare la metà destra, utilizzare la stessa chiave a 24 byte per cifrare gli 8 byte finali della chiave derivata. Combinando i due cifrari a 8 byte (parte sinistra e parte destra), il processo è completato.

Valori di riferimento verificati

Se si desidera eseguire questa procedura autonomamente, potrebbe essere utile verificare i propri risultati confrontandoli con alcuni valori di riferimento noti. Si parta quindi da un BDK a 16 byte pari a 0123456789ABCDEFFEDCBA9876543210 (esadecimale), che rappresenta il valore di chiave di test comunemente utilizzato. Si utilizzi come valore KSN di test 629949012C0000000003. Questi due valori dovrebbero consentire di derivare un IPEK pari a D2943CCF80F42E88E23C12D1162FD547. (Fare riferimento a Parte I di questo articolo per informazioni su come derivare l'IPEK.)

Partendo dall'IPEK sopra indicato, si dovrebbero ottenere i seguenti valori durante la derivazione di una "chiave derivata" (o chiave base DUKPT):

Al primo passaggio attraverso il blocco "if" del ciclo del contatore KSN, il valore BaseKSN sarà 49012C0000000002 e curKey diventerà B58CDA5C7A1E9FF5E7335B988626D01A dopo generateKey().

Al secondo passaggio attraverso il ciclo "if" del contatore, avrai elaborato entrambi i bit "ON" del contatore e quindi il tuo BaseKSN sarà 49012C0000000003 e il curKey risultante sarà 841AB7B94ED086EBC2B8A8385DA7DFCA. (Ricorda: stai eseguendo l'OR dei bit del contatore, dal MSB, nel BaseKSN. Se il contatore termina con 0x0F, il BaseKSN passerà da 49012C0000000008 a 49012C000000000C, poi a 49012C000000000E e infine a 49012C000000000F man mano che si applicano i bit in OR successivamente.)

La "chiave derivata" sarà quindi 841AB7B94ED086EBC2B8A8385DA7DFCA.

Dopo aver eseguito lo XOR con la costante della variante dati, la chiave derivata cambierà in 841AB7B94E2F86EBC2B8A8385D58DFCA.

Dopo aver cifrato le metà superiore e inferiore di quest'ultimo valore utilizzando una chiave di espansione EDE3 pari a 841AB7B94E2F86EBC2B8A8385D58DFCA841AB7B94E2F86EB, si dovrebbe ottenere una chiave dati finale di F739AEF595D3877F731782D28BB6AC4F. Vale a dire: utilizzando il valore della chiave EDE3 a 24 byte per cifrare 841AB7B94E2F86EB, si dovrebbe ottenere un testo cifrato di F739AEF595D3877F, e utilizzando la stessa chiave per cifrare C2B8A8385D58DFCA, si dovrebbe ottenere un testo cifrato di 731782D28BB6AC4F. Concatenando i due testi cifrati, il processo è completato. Hai ora una chiave a 16 byte con cui puoi decifrare i dati della transazione il cui KSN era 629949012C0000000003.

Codice di esempio: lo strumento di cifratura/decifratura ID TECH

Per consultare il codice sorgente completo di tutte le routine di derivazione delle chiavi DUKPT trattate in questa sede, assicurati di scaricare (ed esaminare il codice sorgente del) nostro strumento basato su HTML e JavaScript Strumento di Cifratura/Decifratura, che consente di calcolare gli IPEK, derivare tutte e 3 le varianti di chiave DUKPT, cifrare o decifrare dati tramite TDES o AES e molto altro ancora. Puoi utilizzare l'eccellente set di strumenti della console per sviluppatori di Chrome per scorrere il codice dello strumento in tempo reale, ispezionare i valori delle variabili man mano che cambiano, impostare breakpoint e altro. È un ausilio didattico straordinario. Ed è gratuito! Quindi scarica lo Strumento di Cifratura/Decifratura, provalo e parlane con i tuoi colleghi. Per quanto ne so, è l'unica implementazione DUKPT in puro JavaScript disponibile sul Web.