Technischer Beitrag
Kreditkartendaten entschlüsseln, Teil II
Kunden fragen häufig: Wie kann ich die Daten entschlüsseln, die von meinem ID TECH Kreditkartenlesegerät ausgegeben werden?
Die Antwort: Sie müssen den Algorithmus kennen, der zur Verschlüsselung der Daten verwendet wurde, sowie den zugehörigen Schlüssel. Anschließend können Sie die Daten mit diesem Schlüssel entschlüsseln.
Heutzutage werden nahezu alle Kreditkartendaten mit einem Einmalschlüssel verschlüsselt, der über ein spezielles Schlüsselverwaltungsverfahren namens DUKPT (Derived Unique Key Per Transaction) erzeugt wird. Es ist wichtig zu verstehen, dass im DUKPT-Verfahren jede Transaktion ihren eigenen Schlüssel besitzt. Dieser Schlüssel kann für keine weitere Transaktion wiederverwendet werden – Replay-Angriffe sind daher ausgeschlossen.
Die entscheidende Frage lautet: Wie lässt sich ein DUKPT-Schlüssel ableiten, der eine bestimmte Transaktion entschlüsselt? Die Antwort: Im Wesentlichen benötigen Sie die Key Serial Number (KSN) der Transaktion sowie einen speziellen Wert, den sogenannten IPEK (Initial Pin Encryption Key) – also den Anfangsschlüssel, der in das Kreditkartenlesegerät eingespielt wurde. Der IPEK selbst wird aus einem streng geheimen Schlüssel abgeleitet, der niemals in ein Lesegerät injiziert wird: dem BDK (Base Derivation Key). Im Gegensatz zum BDK ist der IPEK an ein bestimmtes physisches Gerät gebunden. (Aus einem einzigen BDK lassen sich viele eindeutige IPEKs ableiten.) Falls Ihnen der IPEK Ihres Geräts nicht bekannt ist – was naheliegend ist, da der IPEK nirgendwo schriftlich festgehalten wird –, können Sie ihn aus einer KSN und einem Base Derivation Key ableiten. Die dafür erforderliche Methode wird in Teil I dieses Artikels.
Die Ableitung eines Sitzungsschlüssels (auch als Working Key oder schlicht „Data Key" bezeichnet) lässt sich am besten als dreistufiger Prozess verstehen. Die Schritte sind:
1. Verwenden Sie BDK und KSN, um den IPEK abzuleiten. (Weitere Details hierzu finden Sie Teil I dieses Artikels .)
2. Verwenden Sie den ANSI X9.24 (DUKPT)-Schlüsselableitungsalgorithmus, um aus dem KSN und dem IPEK einen Basisschlüssel bzw. einen initialen „abgeleiteten Schlüssel" zu erzeugen.
3. Wandeln Sie den in Schritt 2 abgeleiteten Schlüssel in einen Data Key, PIN Key oder MAC Key Ihrer Wahl um. (Beachten Sie, dass die meisten Kreditkartenlesegeräte zwar so konfiguriert sind, dass sie die Data-Variante des Schlüssels als Transaktionssitzungsschlüssel verwenden, einige jedoch tatsächlich stattdessen die PIN-Variante nutzen.)
Schauen wir uns genauer an, was die Ermittlung des „abgeleiteten Schlüssels" (Schritt 2) erfordert, da dies bei weitem der aufwändigste Teil des dreistufigen Prozesses ist. Sobald wir den abgeleiteten Schlüssel haben, erläutern wir, wie er in eine Data-, PIN- oder MAC-Variante umgewandelt wird – was vergleichsweise einfach ist.
Im Folgenden verwenden wir eine Reihe von Pseudocode-Beispielen, aber keine Sorge: Vollständigen, funktionsfähigen Quellcode (in JavaScript) für alle nachfolgenden Schritte finden Sie in unserem beliebten Verschlüsselungs-/Entschlüsselungstool. (Probieren Sie es jetzt aus, falls Sie es noch nicht getan haben. Es handelt sich um eine in sich geschlossene Webseite, die in jedem modernen Browser funktioniert.)
Einen Schlüssel ableiten
Um den Basisschlüssel abzuleiten, aus dem eine Data-, PIN- oder MAC-Variante erstellt werden kann, benötigen Sie einen Transaktions-KSN und einen IPEK. Sobald Sie diese haben (nochmals: siehe Teil I dieser Serie), gehen Sie wie folgt vor:
1. Entnehmen Sie die unteren (rechtsseitigen) 8 Bytes Ihres 10-Byte-KSN. Die oberen zwei Bytes werden verworfen.
2. Erstellen Sie eine Variable BaseKSN, die eine maskierte Version Ihres 8-Byte-KSN enthält. Die maskierte Version erhalten Sie, indem Sie den 8-Byte-KSN aus Schritt 1 mit dem (hexadezimalen) Wert 0xFFFFFFFFFFE00000 per AND-Operation verknüpfen.
3. Ermitteln Sie die Zählerbits aus Ihrem ursprünglichen (nicht maskierten!) 10-Byte-KSN, indem Sie dessen unterste drei Bytes mit 0x1FFFFF per AND-Operation verknüpfen. (Zur Erinnerung: Die untersten 21 Bits eines KSN bilden den Transaktionszähler.) Diesen Wert speichern wir in einer Variablen namens (wie sonst?) counter.
4. Kopieren Sie Ihren 16-Byte-IPEK in eine Variable namens curKey.
5. Nun müssen wir eine Schleife einrichten. Bei jedem Durchlauf der Schleife prüfen wir die Zählerbits (beginnend mit dem obersten Bit, also dem 21. Bit; beim zweiten Durchlauf prüfen wir das 20. Bit, dann das 19. Bit und so weiter). Jedes Mal, wenn wir ein gesetztes Bit finden, wird es per OR in den BaseKSN eingebunden, und anschließend wird generateKey() aufgerufen, um curKeyzu aktualisieren. Der BaseKSN akkumuliert mit jedem Schleifendurchlauf Bits, und der curKey-Wert wird bei jedem gefundenen gesetzten Zählerbit aktualisiert.
Was macht generateKey() ? Gute Frage! Wenn Ihre Programmiersprache BigInteger-Arithmetik unterstützt, sieht der Code in etwa so aus:
Gut. Sie sehen, dass der 16-Byte-Schlüssel maskiert und anschließend verwendet wird, um den 8-Byte-Wert ksn zu verschlüsseln und so die linke Hälfte (die linken 8 Bytes) eines neuen Schlüssels zu erhalten. Die rechte Hälfte des neuen Schlüssels ist ein Chiffrat, das aus demselben ksn erzeugt wird, jedoch mit einem unmaskierten Schlüssel.
Abschließend müssen Sie wissen, was encryptRegister() sieht folgendermaßen aus. Hier ist sie:
Zu beachten ist, dass Cipher Block Chaining hier eigentlich bedeutungslos ist, da wir einen 8-Byte-Wert (einen einzigen Datenblock) verschlüsseln. Es gibt nichts zu „verketten". Es ist im Code lediglich enthalten, weil die Verschlüsselungsroutine zufällig einen Parameter erfordert, der das Chaining mit Ja oder Nein bestätigt.
Außerdem ist zu beachten, dass wir für die Verschlüsselung einen 8-Byte-Schlüssel verwenden. TDES wechselt automatisch zu Single-DES, wenn der Schlüssel nur 8 Byte lang ist. Das liegt daran, dass ein 8-Byte-Schlüssel bei Triple-DES zu einem Verschlüsselungs-/Entschlüsselungs-/Verschlüsselungszyklus führen würde, der einem einfachen Verschlüsselungsvorgang entspricht.
In verständlicher Sprache ausgedrückt bedeutet dies: Die Routine verwendet die oberen 8 Byte eines 16-Byte-Schlüssels, um einen speziellen Wert zu verschlüsseln, der durch XOR-Verknüpfung der unteren 8 Byte des Schlüssels mit dem (8-Byte-)KSN entsteht. Das Ergebnis ist ein Einweg-Hash des KSN.
Alles zusammengenommen ergibt die Schleife aus Schritt 5 einen curKey -Wert, der als Basisschlüssel dient, aus dem wir Varianten für Daten, PIN oder MAC ableiten können. (Die Schleife in Schritt 5 ist – oder sollte – Teil einer Funktion sein, die letztendlich curKey zurückgibt, also den Basisschlüssel.)
Es ist nun an der Zeit, diese drei „Schlüsselvarianten"-Optionen genauer zu betrachten.
Erstellen von Daten-, PIN- und MAC-Schlüsselvarianten
ANSI X9.24 erlaubt es, dass ein DUKPT-Schlüssel eine von drei abschließenden Formen annimmt, die als Varianten bezeichnet werden: MAC, PIN und Daten. Die Frage, wofür diese verschiedenen Schlüsseltypen jeweils verwendet werden, klären wir zu einem späteren Zeitpunkt und konzentrieren uns zunächst darauf, wie sie erstellt werden.
Ausgangspunkt für jede der Varianten ist ein DUKPT-Basisschlüssel (der abgeleitete Schlüssel, den wir in Schritt 5 weiter oben als curKey bezeichnet haben). Um die MAC-Variante zu erhalten, muss der Basisschlüssel (der „abgeleitete Schlüssel") lediglich mit einer speziellen Konstante XOR-verknüpft werden:
Die PIN-Variante wird auf ähnliche Weise erstellt, jedoch unter Verwendung einer anderen Konstante:
Die Data-Variante erfordert wiederum eine andere Konstante:
Bei den MAC- und PIN-Varianten bildet die XOR-Operation den abschließenden Schritt bei der Erstellung des jeweiligen Session Keys. Bei der Data-Variante ist es üblich, einen zusätzlichen Schritt durchzuführen, der einen Einweg-Hash umfasst (um jede Möglichkeit auszuschließen, einen Data Key in einen MAC Key zurückzutransformieren). In Pseudocode:
Im Klartext: Zunächst wird eine 24-Byte-Version des abgeleiteten Schlüssels erstellt, indem die EDE3-Erweiterungsmethode verwendet wird. (Dies bedeutet schlicht, dass die ersten 8 Bytes eines 16-Byte-Schlüssels an dessen Ende angehängt werden, wodurch ein 24-Byte-Schlüssel entsteht, bei dem die ersten und letzten 8 Bytes identisch sind.) Mit diesem Schlüssel werden die ersten 8 Bytes des 16-Byte-abgeleiteten Schlüssels mittels TDES verschlüsselt, wodurch ein 8-Byte-Chiffretext entsteht. Dies ist die linke Hälfte des endgültigen Data Keys. Zur Erstellung der rechten Hälfte wird derselbe 24-Byte-Schlüssel verwendet, um die unteren 8 Bytes des derivedKey zu verschlüsseln. Die beiden 8-Byte-Chiffretexte (linkes und rechtes Teilstück) werden zusammengeführt, und der Vorgang ist abgeschlossen.
Bekannte Referenzwerte
Wenn Sie dies nachvollziehen möchten, empfiehlt es sich, die eigenen Ergebnisse gegen bekannte Referenzwerte zu prüfen. Verwenden Sie dazu einen 16-Byte-BDK mit dem Wert 0123456789ABCDEFFEDCBA9876543210 (hexadezimal) – dies ist der Testschlüsselwert, der allgemein verwendet wird. Testen Sie außerdem den KSN-Wert 629949012C0000000003. Mit diesen beiden Werten sollten Sie einen IPEK von D2943CCF80F42E88E23C12D1162FD547 ableiten können. (Siehe Teil I dieses Artikels , wenn Sie nachvollziehen möchten, wie der IPEK abgeleitet wird.)
Ausgehend vom oben genannten IPEK sollten bei der Ableitung eines „derived key" (oder DUKPT-Basisschlüssels) die folgenden Werte erscheinen:
Beim ersten Durchlauf durch das „if" der KSN-Counter-Schleife wird Ihr BaseKSN den Wert 49012C0000000002 aufweisen und curKey wird nach generateKey().
Beim zweiten Durchlauf durch das „if" der Zählerschleife haben Sie beide „ON"-Bits des Zählers verarbeitet. Damit lautet Ihre BaseKSN 49012C0000000003 und der resultierende curKey 841AB7B94ED086EBC2B8A8385DA7DFCA. (Zur Erinnerung: Die Zählerbits werden beginnend mit dem MSB per OR-Verknüpfung in die BaseKSN eingebunden. Endet der Zähler auf 0x0F, ändert sich die BaseKSN schrittweise von 49012C0000000008 über 49012C000000000C und 49012C000000000E zu 49012C000000000F.)
Ihr „Derived Key" lautet somit 841AB7B94ED086EBC2B8A8385DA7DFCA.
Nach der XOR-Verknüpfung mit der Datenvarianten-Konstante ändert sich der Derived Key zu 841AB7B94E2F86EBC2B8A8385D58DFCA.
Nach der Verschlüsselung der oberen und unteren Hälfte des letzteren Werts mithilfe eines EDE3-Erweiterungsschlüssels von 841AB7B94E2F86EBC2B8A8385D58DFCA841AB7B94E2F86EB ergibt sich ein finaler Datenschlüssel von F739AEF595D3877F731782D28BB6AC4F. Das bedeutet: Wird der 24-Byte-EDE3-Schlüsselwert verwendet, um 841AB7B94E2F86EB zu verschlüsseln, ergibt sich der Chiffrewert F739AEF595D3877F; die Verschlüsselung von C2B8A8385D58DFCA mit demselben Schlüssel liefert den Chiffrewert 731782D28BB6AC4F. Durch Verkettung der beiden Chiffrewerte ist der Vorgang abgeschlossen. Sie verfügen nun über einen 16-Byte-Schlüssel, mit dem Sie die Daten aus der Transaktion entschlüsseln können, deren KSN 629949012C0000000003 lautete.
Codebeispiel: Das ID TECH Encrypt/Decrypt Tool
Den vollständigen Quellcode für alle hier beschriebenen DUKPT-Schlüsselableitungsroutinen finden Sie in unserem HTML- und JavaScript-basierten Tool. Laden Sie es herunter und sehen Sie sich den Quellcode an: Verschlüsselungs-/EntschlüsselungstoolDas Tool berechnet IPEKs, leitet alle drei DUKPT-Schlüsselvarianten ab, ver- und entschlüsselt Daten mit TDES oder AES und bietet noch viele weitere Funktionen. Mit der hervorragenden Entwicklerkonsole von Chrome lässt sich der Code des Tools in Echtzeit schrittweise durchlaufen, Variablenwerte können beim Ändern inspiziert und Haltepunkte gesetzt werden. Es ist eine außerordentlich wertvolle Lernhilfe – und obendrein kostenlos! Laden Sie das Verschlüsselungs-/Entschlüsselungstoolherunter, experimentieren Sie damit und empfehlen Sie es weiter. Nach meinem Kenntnisstand handelt es sich um die einzige reine JavaScript-DUKPT-Implementierung im Web.
