Frage:
Hashing einer Kreditkartennummer zur Verwendung als Fingerabdruck
FloatingRock
2014-07-16 20:23:13 UTC
view on stackexchange narkive permalink

Transforming the credit card number into a fingerprint

Wie kann eine Kreditkartennummer am besten gehasht werden, damit sie für Fingerabdrücke verwendet werden kann (dh wenn Sie zwei Hashes vergleichen, werden Sie wissen, ob die Kartennummern übereinstimmen oder nicht)? ?

Idealerweise suche ich nach Empfehlungen, welches Hash + Salz für diesen Anwendungsfall gut geeignet sein könnte. Der Hash würde eine bestimmte Kartennummer eindeutig identifizieren. Mit diesem Attribut können Sie beispielsweise überprüfen, ob zwei Kunden, die sich bei Ihnen angemeldet haben, dieselbe Kartennummer verwenden. (da Sie im Klartext keinen Zugriff auf die Kartennummern hätten)

Fingerprints match

Informationen hierzu finden Sie in den Stripe API-Dokumenten und suchen Sie nach Fingerabdruck . Hier habe ich zum ersten Mal von diesem Konzept gehört. Die Kreditkarteninformationen werden auf einem sicheren Computer (irgendwo im Stripe-Backend) gespeichert, auf den der Kunde nicht zugreifen kann, und die API gibt den Fingerabdruck zurück, damit der API-Verbraucher Vergleiche anstellen kann (z. B. um Fragen wie Wurde diese Karte schon einmal verwendet? ).

Lassen Sie uns dies klarstellen, denn ich weiß, dass Sie fragen werden: Ich versuche nicht, sie zu replizieren. Ich bin nur neugierig zu verstehen, wie dies implementiert werden kann

Überprüfen Sie sie wie ein Passwort oder müssen Sie sie abfragen können? Das Salzen würde die Abfragefähigkeit sofort beeinträchtigen.
Wenn Sie es vor Bruteforce-Vermutungen wie einem Kennwort schützen möchten, müssen Sie es wie ein Kennwort behandeln, außer mit CC-Nummern. CC-Hash und Salt, die diesem Benutzer zugeordnet sind. Ein guter langsamer Hash mit Dehnung, sicherem Vergleich usw.
Salz + Hasch * funktioniert * also nicht *, weil Salze einzigartig sind. Wenn also zwei identische Kartennummern einmal gesalzen sind, werden unterschiedliche Hashes erzeugt, und Sie können nicht feststellen, dass die Kartennummer mit einem bereits vorhandenen gesalzenen Hash derselben Kartennummer übereinstimmt, da die Salze unterschiedlich sind.
@Xander Danke für die Klarstellung. Ok, dann kein Salz. Welchen Hash würden Sie vorschlagen?
Ich stimme der Antwort von [u2707] (http://security.stackexchange.com/a/63251/12) eher zu, und wenn Sie die Kreditkartennummern nicht sicher speichern können, halte ich es auch nicht für sinnvoll, Hashes zu speichern . Ich kann Ihren Kunden nicht empfehlen, dies zu tun.
Weiterleiten an Paypal?
@Xander: Das gleiche Salz wiederverwenden. Das Salz wird normalerweise unverschlüsselt gelagert. Zu Vergleichszwecken sollten Sie es einfach abrufen und mit demselben Salz aufwärmen. Überprüfen Sie, ob es übereinstimmt. Davon abgesehen würde ich keine Kreditkartennummer speichern.
@staticx Das ist kein Salz, es ist ein Pfeffer, und es ist aus Sicherheitsgründen nicht besonders wertvoll, wenn Sie versuchen, Hash-Cracking zu verhindern, da Sie immer noch nur einen einzigen Satz von Hashes berechnen müssen, um alle Werte wiederherzustellen.
@Xander: Interessant, habe diesen Begriff noch nie gehört. Ich habe vor ungefähr 2-3 Jahren ein PCI-Audit mit einem Salz, ich meine Pfeffer, bestanden.
@staticx Es ist eine Art kitschiger Begriff, den ich kenne, aber da ein Salz per Definition global einzigartig sein muss, ist ein Wert, der mehr als einmal verwendet wird, nicht qualifiziert.
@Xander: Ich persönlich bevorzuge einen One-Way-Token.
@staticx Um dies in einen Zusammenhang zu bringen, lesen Sie die [Stripe API-Dokumente] (https://stripe.com/docs/api) und suchen Sie nach "Fingerabdruck". Es ist das gleiche Konzept. Die Kreditkarteninformationen werden auf einem sicheren Computer gespeichert, auf den der Kunde (API-Verbraucher) nicht zugreifen kann. Der Fingerabdruck wird jedoch zurückgegeben, damit er Vergleiche anstellen kann.
Wie wird der Trunk verschlüsselt und wie wird die Karte im Trunk verschlüsselt?
Nicht ganz sicherheitsrelevant, aber ist es Ihr Ziel, es so zu gestalten, dass 2 Kunden nicht denselben CC verwenden können? Ich kann mir schnell einige Situationen vorstellen, in denen zwei separate Konten denselben CC verwenden: ein Vater und ein Sohn, die beide Videospiele spielen, und der Vater verwendet seinen CC, um die Spiele des Sohnes auf seinem eigenen Konto zu bezahlen; ein Ehepaar, das separate Amazon-Konten hat, um seine Kindle-Sammlungen auseinander zu halten, aber für beide Einkäufe eine Kreditkarte verwendet; Ein Unternehmen, das mehrere separate Office365-Organisationen benötigt, diese jedoch mit der Firmenkreditkarte bezahlt. Vermeiden Sie es, Dinge einzigartig zu machen, die das vielleicht nicht sind.
@NateKerkhofs ist so, dass der Kunde (der Verbraucher der API) entscheiden kann, was in jedem Szenario zu tun ist. Wenn Sie Kunden gruppieren möchten, die denselben CC verwenden, benötigen Sie einen Fingerabdruck, um das Token zu identifizieren - genau das bietet Stripe. Mit diesem Fingerabdruck können Sie machen, was Sie wollen.
Nur weil es jemand tut, heißt das in Ihrer letzten Bearbeitung nicht, dass es morgen verpönt sein wird. Was ist, wenn der Stripe-Server nicht verfügbar ist? Möchten Sie wirklich an diesen Service gebunden sein?
Ich habe Hash (fixed_salt_or_pepper + PAN) verwendet, um Karten auf der schwarzen Liste zu indizieren, und das hat die PCI-Prüfung bestanden (und FISMA, glaube ich). Wir haben diesen Mechanismus jedoch nicht zum Speichern der verwendbaren Karten des Kunden verwendet.
@staticx Wenn der Server von Stripe nicht verfügbar ist und Sie sie für Ihre Händlerdienste verwenden, können Sie ohnehin keine Karten / Transaktionen verarbeiten. Daher ist es unerheblich, ob Sie sich auch für diese Funktion auf sie verlassen.
Acht antworten:
Xander
2014-07-17 00:06:37 UTC
view on stackexchange narkive permalink

Ok, wenn dies eine Geschäftsanforderung ist, die Sie erfüllen müssen (überprüfen Sie, ob bereits eine Karte im System vorhanden ist), würde ich dies so tun.

Erstens ermöglicht PCI-DSS, dass eine PAN (die primäre Kontonummer oder Kreditkartennummer) in Hash-Form unter Verwendung von "starker Kryptographie" gespeichert wird, und sie empfehlen (erfordern jedoch nicht), dass a Salz auch verwendet werden. PCI-DSS v3 § 3.4 (PDF-Link) Der Grund besteht darin, die Fähigkeit einer böswilligen Partei, die den Hash erhält, daran zu hindern, die PAN zu bestimmen, die als Eingabe für den Hash verwendet wurde.

Zweitens ist Ihr Plan, dies in einem separaten, sicheren System zu speichern und nur über eine API verfügbar zu machen, eine gute Tiefenmaßnahme. Wenn ich dies implementieren würde, würde ich keinen Hash an das Primärsystem zurücksenden lassen. Ich würde einfach den Hash als Parameter für den API-Aufruf verwenden und die API "true" oder "false" zurückgeben lassen, je nachdem, ob der Hash ist bereits im System vorhanden oder nicht.

Für die Hashing-Funktion besteht der Schlüssel zum Verhindern der Wiederherstellung der Eingaben (wie von PCI-DSS gefordert) darin, einen Algorithmus auszuwählen, mit dem Sie den Prozess ausführen können rechenintensiv, daher ist die Aufgabe, den relativ kleinen Eingaberaum gültiger PANs brutal zu erzwingen, relativ langsam. SHA-512, vorgeschlagen durch eine andere Antwort, ist nicht dieser Algorithmus. Betrachtet man die von hashcat.net bereitgestellte Testmatrix für Hash-Cracking, so kann die schnellste Maschine in ihrer Matrix fast 2 Milliarden SHA-512-Hashes pro Sekunde berechnen. Bei einem geschätzten Eingabebereich von ungefähr 30.000.000.000.000 Karten ** bedeutet dies, dass Sie ungesalzen den SHA-512 jeder dieser PANs in etwas mehr als 4 Stunden berechnen und die Kartennummern für jede Karte in der Datenbank haben können, falls dies jemals der Fall sein sollte gestohlen werden.

Was wir also brauchen, ist eine langsame Hash-Funktion. Die Definition von langsam ändert sich jedoch ständig, wenn Computer schneller werden und sich die Technologie weiterentwickelt. Dies bedeutet, dass eine sichere Hash-Funktion eine Funktion mit einem einstellbaren Arbeitsfaktor ist, sodass Sie im Laufe der Zeit den Rechenaufwand erhöhen können, der zum Berechnen des Hash einer bestimmten Eingabe erforderlich ist. Es gibt mehrere Kandidatenalgorithmen, die diese Kriterien erfüllen, einschließlich PBKDF2, bcrypt und scrypt. Der allgemeine Konsens für Passwort-Hashing ist bcrypt, und das würde ich hier vorschlagen. Stellen Sie die Kosten so hoch ein, wie es Ihre Anwendung zulässt. Es ist wahrscheinlich nicht etwas, das Sie furchtbar häufig berechnen werden (ich würde mir vorstellen, dass Sie abhängig von Ihrer Anwendung x Hashes pro Minute oder Stunde oder Tag anstatt pro Sekunde betrachten werden) und höher Je höher die Kosten, desto schwieriger wird es für einen Gegner, der den Hash erfasst, brutale Gewalt anzuwenden.

** Meine Schätzung basiert auf einer 9-stelligen Kontonummer, einer berechenbaren Prüfziffer, die die Komplexität nicht erhöht, und einer WAG von 30.000 aktiven Bankidentifikationsnummern (die ersten 6 Ziffern der Karte) basierend auf eine Liste, die ich gefunden habe.

Ich denke du bist zu optimistisch. Bcrypt widersteht FPGAs sehr gut, und ich würde annehmen, dass die letzten 4 Ziffern dem Angreifer bekannt sind.
@CodesInChaos Nun, insgesamt bleibt mein Rat, dies in der Praxis überhaupt nicht zu tun, bestehen. Wenn Sie jedoch PCI folgen, sind die abgeschnittenen Kartennummern theoretisch gut von den Hashes getrennt, und eine Verletzung der einen beeinträchtigt die andere nicht. In der Praxis ... * Achselzucken. * In einer theoretischen Implementierung würden Sie angesichts der von Ihnen erwähnten mangelnden Resistenz gegen FPGA-basierte Angriffe vorschlagen, dass Verschlüsselung eine bessere Option ist?
Kreditkartennummern sind ohnehin in erster Linie unsicher. Die meisten Seriennummernsysteme für Spiele haben mehr Entropie. Wann werden wir sie los?
@CodesInChaos was würden Sie tun? (wenn nichts zu tun keine Option war)
@CodesInChaos Da BCrypt jedes Mal ein anderes Salz verwendet, können Sie die resultierenden Hashes nicht wirklich vergleichen. Es sei denn natürlich, Sie haben das gleiche Salz verwendet, was mir nicht sehr verschlüsselt erscheint.
John Downey
2014-07-17 19:08:33 UTC
view on stackexchange narkive permalink

Ich kann nicht kommentieren, wie Stripe das macht, aber ich kann Ihnen genau sagen, wie Braintree das macht (weil ich dort arbeite). Wenn ich raten müsste, verwendet Stripe wahrscheinlich eine ähnliche Methode.

In der Braintree-API bieten wir eine eindeutige Nummernkennung für eine Kreditkarte an. Diese Kennung ist ein zufälliger undurchsichtiger Token, der für die in unserem System gespeicherte Kartennummer immer gleich ist. Der Startwert für diese Nummer ist je nach Händler in unserem System unterschiedlich, sodass Sie sie nicht zwischen Händlern vergleichen können.

Wenn eine neue Karte eingeht, prüfen wir sie, indem wir sie mit einer Spalte mit Hash + Salz vergleichen. Wenn es mit dieser vorhandenen Spalte übereinstimmt, wissen wir, dass wir dieselbe eindeutige Nummernkennung zurückgeben können. Wenn es keinem vorhandenen Datensatz entspricht, verwenden wir einen kryptografisch sicheren Pseudozufallszahlengenerator, um eine neue eindeutige Nummernkennung zu erstellen und sicherzustellen, dass sie nicht mit einer vorhandenen in Konflikt steht.

Auf diese Weise wird der Hash ausgeführt + Salted Value verlässt unser Backend nie, aber wir können einem Händler dennoch die Möglichkeit bieten, gespeicherte Kreditkarten eindeutig zu identifizieren.

Brillant! @Xander, Ich würde gerne Ihren Kommentar zu den Sicherheitsaspekten (und allen anderen in dieser Angelegenheit) hören.
@FloatingRock Meiner Ansicht nach erweitert dies im Wesentlichen die von mir beschriebene Methode, indem (a) die PAN vor dem Hashing peppert und dann (b) ein zusätzliches eindeutiges, zufällig generiertes Token (oder ein Fingerabdruck) neben dem Hash gespeichert wird. Sie müssen weiterhin die App und die Datenbank stark sichern und die Hashes und Token speichern. Sie können das Token dann jedoch an die Front-End-App zurückgeben, um es zu behalten, und es werden keine Informationen zu der Karte angezeigt, mit der es verknüpft ist . Es ist insofern sehr schön, als Sie damit Funktionen an das Front-End auslagern können, ohne dass Sie zusätzlichen Kartendaten ausgesetzt sind.
+1 Ich LIEBE es absolut, dass das Token vollständig getrennt ist, da es überhaupt nicht von der PAN abgeleitet ist.
@Xander: Dies ist besser, weil Sie die gehashte und gesalzene PAN überhaupt nicht speichern. Es wird jedes Mal neu ausgeführt, wenn die Transaktion stattfindet. Das einzige Problem, das ich dabei sehe, ist, dass Sie rund um die Uhr online sein müssen. Wenn die Internetverbindung jemals ausfällt, können Sie keine Kreditkarten verarbeiten. Früher habe ich einen Kreditkarten-Verarbeitungscode für Parkanwendungen geschrieben, und viele Parkhäuser sind ohne Kassierer vollautomatisiert. Wir mussten eine Methode entwickeln, um die Kreditkarten offline bis zu einem bestimmten Dollarbetrag sicher zu speichern. Sobald es wieder online war, wurden die Transaktionen gelöscht.
Zu dieser Zeit, und ich denke immer noch, war dies eine weniger riskante Situation, da Karten nicht für immer gespeichert wurden und die Datenbank sicher gelöscht wurde, sobald sie auf dem Master-Server gespeichert wurde, auf dem niemals Karteninformationen gespeichert wurden. Wir mussten einen gehärteten PC in die von ADAM erstellte Maschine namens UNO mit spezieller Software als Vermittler einbauen.
@staticx Ich denke, Sie haben ein bisschen verpasst. "Wenn eine neue Karte eingeht, sehen wir sie nach, indem wir sie mit einer Hash + Salted-Spalte vergleichen." Die Hash-PAN * wird * von Braintree gespeichert, und ich gehe von Stripe aus. Das OP möchte wissen, wie diese Implementierung funktioniert.
@Xander: Dann gibt es noch eine Schwachstelle. Der Speicher wird an einen anderen Dienst ausgelagert, in der Hoffnung, dass er sicher ist.
@staticx stimmt, das Backend müsste definitiv gesichert (und PCI-konform) sein. Der Schlüssel ist, dass der mit dem Endbenutzer geteilte Fingerabdruck nicht zum Ableiten der PAN-Periode verwendet werden kann. (eher wie Komma .. es sei denn natürlich, das Backend wurde kompromittiert).
@FloatingRock: Ja, die Korrelation muss nur innerhalb ihrer Datenbank auftreten, da es keine Möglichkeit gibt, den Fingerabdruck oder die eindeutige Nummer anzugeben und eine Kartennummer zurückzugewinnen. Das wäre königlich dumm. Ich denke, Sie erhöhen Ihr Risiko, indem Sie die Kartennummer überall speichern. PCI geht meiner Meinung nach nicht weit genug, um Speicher zu verhindern. Es sollte die Möglichkeit verweigern, die Nummer überall zu speichern. Dies würde zu leichten Unannehmlichkeiten führen, aber nicht so schlimm wie das, was Target oder anderen Einzelhändlern kürzlich widerfahren ist.
@staticx, das theoretisch großartig klingt. In der Praxis gibt es jedoch berechtigte Anforderungen, die die Speicherung dieser Informationen erfordern. Eine wiederkehrende Abrechnung (oder Abonnements) erfordert beispielsweise die Speicherung der Kartennummer.
@FloatingRock: Es ist sehr, sehr schwierig, Kreditkarteninformationen sicher zu speichern. Tatsächlich wurde vor fünf Jahren bekannt gegeben, dass 130 Millionen Kreditkartennummern von großen Einzelhandels- und Finanzunternehmen gestohlen wurden, die über weitaus mehr Ressourcen verfügen, als Sie wahrscheinlich zur Sicherung dieser Daten benötigen. Ich verstehe den Wunsch, wiederkehrende Zahlungen leicht zu ermöglichen, voll und ganz. Denken Sie jedoch darüber nach und verstehen Sie das Risiko, das mit dem Speichern von Kreditkartennummern verbunden ist, bevor Sie sich dazu entschließen. Wenn Sie sich entscheiden, die Kartennummern zu speichern, empfehle ich, einen Sicherheitsexperten mit einer nachgewiesenen Erfolgsbilanz zu beauftragen
In Bezug auf Rückerstattungen könnten Sie theoretisch die abgeschnittene Kartennummer, die mit einem eindeutigen Salz mit dem Namen der Person gehasht wurde, so speichern, dass sie (wie wenn Sie etwas an Target zurückgeben) mit dem sicheren Hash übereinstimmt, wenn die Karte erneut präsentiert wird. Dies würde sich nicht auf Stripe stützen und Sie müssten nicht die vollständige PAN speichern, obwohl Sie die abgeschnittene Version noch schützen müssen. Es gibt verschiedene Tricks, die Sie ausführen können. Wenn Sie sich entscheiden, es irgendwo zu speichern, besteht ein Geschäftsrisiko, als es nur an den Prozessor zu übertragen.
@staticx oh ganz sicher. Ich würde es nicht versuchen, selbst unter Anleitung eines Experten. Ich würde viel lieber jemanden haben, der voll qualifiziert ist, und selbst dann jemanden einstellen, der einen Einbruch versucht. Ich habe lediglich ein Beispiel dafür hervorgehoben, wo es einen legitimen Business Case dafür gibt.
Was hat Sie aus Neugier dazu veranlasst, ein PRNG zum Generieren des Tokens zu verwenden, anstatt beispielsweise eine automatisch inkrementierte PK, die nicht annähernd so viel Rechenleistung und Datenbank-Lookups benötigt, um fehlende Kollisionen sicherzustellen?
@RainFromHeaven Wir wollten, dass der zurückgegebene Wert vollständig undurchsichtig ist und keine Informationen preisgibt. Wenn ein automatisch inkrementierendes Feld verwendet wird, kann dies die relative Anzahl der gespeicherten Karten und die Wachstumsgeschwindigkeit anzeigen
Für alle, die sich zu den PCI-Implikationen äußern. Ich bin damit einverstanden, dass eine gehashte Version einer PAN trivial in die vollständige PAN umgewandelt wird, wenn sie durchgesickert ist (nur wegen der kleinen Domäne von PANs). Braintree ist ein PCI Level 1-Dienstleister, und das Hashing von PANs für diesen Zweck ist in unserem jährlichen PCI-Audit vor Ort enthalten. Der Mehrwert der Verwendung eines Dienstes wie Braintree besteht darin, die PCI-Belastung für die von uns unterstützten Händler zu verringern. Aus diesem Grund bieten wir eine Möglichkeit, Karten eindeutig zu identifizieren, ohne den Hash auf der Händlerseite speichern zu müssen.
@JohnDowney von 'Wenn eine neue Karte eingeht, prüfen wir sie, indem wir sie mit einer Spalte mit Hash + Salz vergleichen.' Meinten Sie, wenn eine neue Karte kommt, vergleichen Sie sie mit jeder Kreditkarte, die Sie bereits haben? Wenn sie geplant sind, müssen Sie sie einzeln ausprobieren?
@Alfred ja, aber Datenbankindizes machen es nicht so beängstigend, wie es sich anhört
u2702
2014-07-16 21:04:16 UTC
view on stackexchange narkive permalink

Das Hashing von Kreditkartennummern ist kein Ersatz für die Sicherung der Daten. Wenn Ihr System nicht sicher genug ist, um unformatierte Kreditkartennummern zu speichern, ist es nicht sicher genug, um CC-Hashes zu speichern.

Dasselbe gilt für alles, was eine feste Größe und einen begrenzten Zeichensatz hat: Geburtsdatum, Telefonnummer , zip usw.

Kreditkarten sind alle sechzehn Ziffern und während 10 ^ 16 wie eine große Zahl erscheint, ist es für Rechenressourcen ziemlich einfach. Wenn ich Ihre Tabelle mit CC # -Hashes habe, kann ich diese leicht mit einer Regenbogentabelle angreifen und eine vollständige Liste der Kreditkarten erhalten. Das Salzen der Werte vor dem Hash macht die Suche unmöglich.

Alle möglichen CC-Werte: weniger als 10 ^ 16.

Stellen Sie sich zum Vergleich vor, Ihre Benutzer haben ein angemessenes 8-stelliges Passwort mit a verwendet 20-Byte-Salz: 62 ^ 28.

(Wenn ich Ihr PCI-Prüfer wäre, würde ich das Hashing von Kreditkarten als gleichbedeutend mit dem Speichern der Kartennummern selbst betrachten.)

Ein Zusatz und ein pedantischer Punkt. Der pedantische Punkt: Einige Kreditkartennummern sind 15-stellig, nicht 16. Das ändert nichts an Ihrer Antwort, aber ich wollte es notieren. Außerdem müssten Sie nicht den gesamten Raum brutal erzwingen. Der erste Satz von Ziffern in einer CC-Nummer ist eines der wenigen bekannten Präfixe, und der letzte ist eine Prüfziffer, sodass der Raum für mögliche gültige Nummern etwas kleiner ist.
Erwischt. Die Frage wurde aktualisiert, um meine Absichten zu klären
@Xander: Ja, und es ist kleiner als man denkt, weil die gesamte Kartennummer den Luhn-Algorithmus bestehen muss.
Noch nicht genug Wiederholungen, um einen Kommentar abzugeben, aber dies ist hauptsächlich auf die vorherigen Antworten gerichtet, die 10 ^ 16 als "maximale" Anzahl von "Zufälligkeiten" vorschlagen - es ist nicht wirklich nahe an 10 ^ 16, da von den 16 Ziffern, die sich zusammensetzen eine Kreditkartennummer, nur die Ziffern 7-15 (einschließlich) identifizieren das Konto - die anderen identifizieren den Typ (Mastercard, Visum usw.), den Aussteller (Bank XXX), den spezifischen Kartentyp (IE Delta Gold Prämien) . Schließlich gibt es eine "Prüfsumme", die bedeutet, dass Sie (schnell für einen Computer im Vergleich zum Berechnen eines Hashs) eine andere Ziffer entfernen können, wenn sich dies nicht summiert, so realistisch sind Sie l
"etwas weniger als 10 ^ 16" - ja, definitiv etwas kleiner als 10 ^ 16, einfach zu faul, um zu rechnen.
John Deters
2014-07-17 05:31:09 UTC
view on stackexchange narkive permalink

Die Antwort wird Sie enttäuschen: Wenn ein Dienst / Orakel / Hash Ihnen sagen kann, ob eine Eingabenummer gespeichert ist, kann sie mit sehr wenig roher Gewalt gebrochen werden.

Bedenken Sie, dass in weiten Teilen des Landes Kreditkarten von relativ wenigen Banken in ihrer geografischen Region ausgestellt werden. Sie können die BIN-Nummern für die beliebtesten dieser Banken ganz einfach lernen. Angenommen, Sie haben eine Quittung aus einem Geschäft in Memphis und dort steht VISA **** 1234. Die Wahrscheinlichkeit liegt bei etwa 20%, dass es sich um eine von zehn verschiedenen BINs handelt, die zu den größten Banken in der Region Memphis gehören. Das sind 10 ^ 1 Vermutungen für die ersten sechs Ziffern. Als nächstes kennen Sie die letzten 4, weil sie auf der Quittung abgedruckt sind. Das sind jetzt nur 10 ^ 1 Vermutungen, die 10 der 16 Ziffern abdecken. Von den verbleibenden sechs Ziffern iterieren Sie über 5 und berechnen Sie die letzte mit Luhn. Das sind 10 ^ 6 Tests, die in 20% der Fälle eine gültige Kontonummer ergeben.

Alles, was Sie tun müssen, um eine Nummer zu testen, ist eine 100.000-malige Schleife durch den Dienst. Es spielt keine Rolle, ob der Dienst einen Hash oder eine Verschlüsselung oder einen Zauberstab verwendet, um die Kontonummern zu schützen, solange er Ihnen sagt, ob Ihre Eingabe übereinstimmt oder nicht.

Möglicherweise stellen Sie fest, dass dies nur in etwa 20% der Fälle funktioniert. Bedenken Sie, dass der Typ, der Target gestohlen hat, 40 Millionen Kontonummern genommen hat und nicht alle verkaufen konnte, da es nicht genug Gauner auf der Welt gab, um so viele zu kaufen. 20% davon sind 8 Millionen, und wahrscheinlich hat er auch nicht so viele verkauft. 20% sind also gut genug für einen Angreifer.

Ich habe die Frage mit einem Gedanken aktualisiert. Viele von Ihnen halten diese Praxis für unsicher, daher ist möglicherweise eine verantwortungsvolle Offenlegung gegenüber Stripe angebracht.
Und Braintree. Aber ehrlich gesagt ist niemand an dieser Sicherheitsanfälligkeit interessiert, da das Entfernen dieser Sicherheitsanfälligkeit zwangsläufig die geschäftliche Rechtfertigung zunichte machen würde.
Damon
2014-07-17 18:38:25 UTC
view on stackexchange narkive permalink

tl; dr:
Es ist nicht möglich, so etwas wirklich sicher zu machen, aber es kann "wahrscheinlich gut genug" gemacht werden, um brauchbar und akzeptabel zu sein

Bei Ihren Optionen handelt es sich im Grunde genommen um eine Form von verschlüsseltem Speicher (mit dem Risiko, dass Verschlüsselungsschlüssel gestohlen werden, da diese zur Entschlüsselung vorhanden sein müssen) oder um Hashing mit den bekannten Problemen des Hashing Passwörter (eine Kreditkartennummer ist im Grunde ein "Passwort").

Ich würde dies als zweistufiges System implementieren, bei dem die erste Ebene ein einfacher CRC32 und die zweite Ebene ein Vielfaches wäre iterierte sichere Hash-Funktion. Ja, CRC32 ist kein kryptografisch sicherer Hash, aber das spielt in diesem speziellen Fall keine Rolle, da der CRC nicht das schwache Glied ist.
Wenn der Gedanke, einen nicht kryptografisch zu verwenden, Ein sicherer Algorithmus macht Ihnen zu viel Angst. Sie können den CRC dennoch durch einen kryptografisch gesicherten Algorithmus ersetzen und nur z Die niedrigstwertigen 32 (oder 16, für einen größeren Rand) Bits aus dem resultierenden Hash.

Der Grund für diesen Ansatz ist, dass der Bereich möglicher Eingaben nur etwa 39 Bits [1] . Es ist praktisch unmöglich, diesen Schlüsselraum auf wirklich sichere Weise zu hashen, während das System für die vorgesehene Verwendung betriebsbereit bleibt.
Ein Brute-Force-Angriff auf einen 39-Bit-Schlüsselraum ist nicht nur theoretisch machbar, sondern auch recht trivial - es sei denn Jede einzelne Operation ist extrem teuer.

Die Hauptbedrohung, gegen die Sie sich verteidigen müssen, ist der Diebstahl Ihrer Datenbank, gefolgt vom brutalen Erzwingen, dass Ihre Hashes gültige Kartennummern abrufen. Das nächstbeste, was ein Angreifer tun könnte, wäre online abzufragen, ob eine unbekannte Nummer, die mit einer zufällig übermittelten Nummer identisch ist, zuvor verwendet wurde, oder ob eine bereits bekannte gültige Nummer wurde verwendet (keines ist jedoch sehr nützlich!).

Kreditkarten sind normalerweise 5 Jahre gültig. Damit das System sicher ist, muss es mindestens 5 Jahren Brute-Force standhalten. Mit anderen Worten, die für eine einzelne Überprüfung ausgeführte Arbeit muss so rechenintensiv sein, dass eine dedizierte Crackmaschine mit mehreren GPUs nicht mehr als 2 ^ 39 / (5 * 365 * 86400) = 3486,5 Überprüfungen pro Sekunde ausführen kann.

Unter Berücksichtigung der bekannten Zahl von 348 Milliarden pro Sekunde aus dem Jahr 2012 müsste der einzige wirklich sichere Ansatz den Wert von mindestens 100 Millionen Hashing speichern. Unter Berücksichtigung des Mooreschen Gesetzes wären das inzwischen 200 Millionen, und wir ziehen nicht einmal die Möglichkeit in Betracht, dass jemand zwei oder drei solcher Maschinen (oder vielleicht zehn) besitzt.

Dies ist jedoch still berücksichtigt nicht die Tatsache, dass Banken von Natur aus dumm sind und erhöht einfach die vorletzte Ziffer für eine neue gültige Nummer (und aktualisiert die Prüfziffer). Alle meine in den letzten 20 Jahren ausgestellten Kreditkarten hatten dieselbe Nummer, mit Ausnahme der vorletzten Ziffer, die 0, 1, 2, 3, ... erhöht.
Dies bedeutet, dass die Planung für 5 Jahre noch erfolgt ist nicht genug . Jemand, der eine abgelaufene Kreditkartennummer kennt, kann trivial die gültige Nummer der Follower-Karte ableiten. Sie müssen daher eher für so etwas wie 30 Jahre planen, nicht 5 Jahre. Ich überlasse die Extrapolation von Moores Gesetz auf weitere 20 bis 30 Jahre für Hausaufgaben.

Damit das System wirklich, wirklich sicher ist, müsste Ihr Server das ausführen Dies entspricht einer Billion Hashes (oder mehr) pro Überprüfung, die mit einer Rate von beispielsweise 10 Millionen pro Sekunde für eine typische CPU-Implementierung mehr als einen Tag in Anspruch nehmen würden. Mit anderen Worten, das System ist für den vorgesehenen Zweck vollständig unbrauchbar.

Es wird etwas benötigt, das mehrere Größenordnungen schneller ist. Die meisten Abfragen sind negative Abfragen, und ein einfacher, schneller Hash könnte verwendet werden, um 99,9% aller Negative zu entfernen, wenn dies die ohnehin schwache Sicherheit nicht noch schwächer macht. Hier kommt CRC32 ins Spiel.

Wenn die CRC32 von zwei Kreditkartennummern nicht übereinstimmen, ist garantiert, dass die Nummern nicht identisch sind. Meistens ist dies der Fall und Sie können sofort "Nein!" Zurückgeben. Sie können 99,9% der Arbeit überspringen, ohne etwas preiszugeben.
Wenn die CRCs übereinstimmen übereinstimmen, ist dies möglicherweise ein Treffer, es besteht jedoch die Möglichkeit einer Hash-Kollision. Nun wird der sichere kryptografische Hash (der mindestens 160, besser 256 Bit haben würde) berechnet und verglichen. Die Wahrscheinlichkeit einer Kollision ist jetzt vernachlässigbar. Wenn der Hash übereinstimmt, ist es sicher, dass die Anzahl übereinstimmt.

CRC32 enthält 32 Informationsbits. Es ist unmöglich , 39 Bit Informationen aus 32 Bit wiederherzustellen, unabhängig davon, welche Rechenressourcen Sie besitzen. Daher ist die Verwendung des CRC in diesem Fall sicher (oder zumindest nicht weniger sicher als alles andere).

Wie von Ben Voigt hervorgehoben, handelt es sich um Natürlich ist es immer noch möglich, die Informationen zu erraten, die nicht wiederhergestellt werden können, und 7 zu erratende Bits sind keine schreckliche Menge (durch Verketten des Ablaufdatums werden diese 15 Bits erreicht). Das stimmt, aber Sie können nicht viel dagegen tun.

Was ist überhaupt mit CRC und Sicherheit? CRC ist nicht kryptografisch sicher. Es ist relativ einfach, Bits zu manipulieren, um eine gewünschte Ausgabe zu erhalten (hier kein Problem, wäre dies bei Anmeldungen), und die Funktion kann trivial umgekehrt werden (4 Tabellensuchen plus ein paar Verschiebungen und xor) auf eine 32-Bit-Eingabe. ein etwas größeres Problem. Zum Glück, aber dieses Bitmuster ist ziemlich wertlos, da es weder eine gültige Zahl noch eine Teilmenge eines 39-Bit-Musters ist, das eine gültige Zahl sein könnte (außer durch Zufall).

Das brutale Erzwingen des gesamten 39-Bit-Schlüsselraums ist einfacher als der Versuch, Streiche auf dem CRC zu spielen, da dies leider einfach und schnell ist: Eine SSE4.2-Implementierung benötigt ungefähr einen halben Zyklus pro Byte (also) 2 Zyklen pro Hash), was bedeutet, dass ein Desktop-Computer den gesamten Schlüsselbereich in ein oder zwei Sekunden ausführen kann (vorausgesetzt, die Schlüssel werden mit allen in L1 passenden verglichen).

Die umfassende Suche würde alle 39-Bit-Daten anzeigen Muster mit demselben CRC, was bedeutet, dass es sich möglicherweise um Kreditkartennummern handeln kann. Mit dem Luhn-Algorithmus kann der Angreifer sofort 9 von 10 nicht gültigen Nummern verwerfen. Das ist zwar schlecht, aber es ist wirklich nur eine Folge davon, dass nicht zu viele Eingabemöglichkeiten vorhanden sind und eine Prüfziffer oben implantiert ist!

Trotzdem ist der CRC tatsächlich stärker Dieses Szenario ist ein kryptografisch sicherer Algorithmus: Angesichts der weltweit im Umlauf befindlichen 2-3 Milliarden Kreditkarten liegt die Wahrscheinlichkeit einer Kollision mit einem 160-Bit-Hash zwischen 1 und 10 20 sup> und nicht einmal Denken Sie über die Chancen nach, einen 256-Bit-Hash zu verwenden. Dies bedeutet, dass jeder Treffer während Ihrer umfassenden Suche im 39-Bit-Schlüsselbereich sofort Ihnen die einzig garantierte gültige Kartennummer gibt. Ein Treffer auf dem CRC32 gibt Ihnen nur eine von vielen möglichen Zahlen.

Eine Sache, die Sie tun könnten, um Geschwindigkeit gegen Sicherheit einzutauschen, wäre, einige Informationen weiter von der zu entfernen CRC Zum Beispiel könnten Sie einfach die höchstwertigen 8 oder 16 Bits des CRC verwerfen, wodurch diese zu den Bits hinzugefügt werden, die ein Angreifer erraten muss. Dies wird natürlich die Wirksamkeit des Schnittes etwas verringern, aber nicht zu drastisch. Anstatt 99,99% der Arbeit zu beschneiden, könnten Sie am Ende 99% oder 98% beschneiden, was immer noch sehr gut ist.

Die zweite Verifizierungsebene muss, wie oben angegeben, ein kryptografisch sicherer Hash sein, der mindestens eine Million Iterationen ausführt, ähnlich wie bei einem Schlüssel-Stretching-Schema (tatsächlich benötigt er viel mehr als das , aber das System muss auch praktisch verwendbar bleiben.
Der Implementierer muss hier das Risiko gegen die Verwendbarkeit austauschen. Ein Server sollte mindestens noch in der Lage sein, ein paar Dutzend Anforderungen pro zu verarbeiten zweite. Kunden / Händler stimmen nicht zu, wenn das Nachschlagen einer Nummer mehrere Minuten (oder länger) dauert, unabhängig von den Auswirkungen auf die Sicherheit. Es ist auch nicht praktisch, mehr oder weniger einen dedizierten Server pro Händler zu haben.

Da das Abgleichen nur auf Händlerbasis interessant ist, könnte man ein Salz pro Händler konstant verwenden und Kartennummern redundant speichern zusammen mit einem Index der Händler-ID, der in den Zuständigkeitsbereich eines vernünftigen Datenbanksystems fallen sollte.


[1] Eine Kreditkartennummer besteht aus 16 Ziffern wobei die letzte eine von den anderen abgeleitete Prüfsumme ist (Luhn-Algorithmus). Die vorletzte Ziffer ist normalerweise (nicht unbedingt, aber normalerweise) die fortlaufende Kartennummer, beginnend bei Null für die erste Karte des Kontoinhabers, 1 für den Ehepartner oder eine Ersatzkarte, 2 für die nächste Karte danach und so weiter Die ersten drei Ziffern kodieren den Kartenaussteller und die Bank und verwenden nur etwa die Hälfte der möglichen Anzahl dreistelliger Kombinationen.
Insgesamt bleiben uns also 12 und 13 vollständige Dezimalstellen der Entropie, die liegt irgendwo zwischen etwas mehr als 36 Bit und 39 Bit.

Ich würde empfehlen, das Ablaufdatum mit der Nummer zu verketten, da dies die Situation etwas weniger miserabel macht. Meine Kreditkarten sind immer 5 Jahre gültig (ich bin mir nicht sicher, ob dies die universelle Regel ist, aber ich würde es annehmen). Wenn Sie also das Ablaufdatum hinzufügen, werden 5 * 12 Möglichkeiten oder 5,9 Bit hinzugefügt (diese sind so gut wie kostenlos). da brauchst du die Ablaufdaten sowieso in einer Transaktion!).

Danke Damon. Nur zur Verdeutlichung, RE: _ (nur eine Abfrage vom Typ "Hat diese bestimmte Person diese Nummer schon einmal verwendet" möglich) ._ Wenn ich ein Händler bin, der Stripe verwendet, ist es mir egal, ob die Karte mit einer anderen verwendet wurde Kaufmann oder nicht. Der Umfang wäre auf die Karten beschränkt, die bei einem bestimmten Händler (d. H. Me) verwendet werden.
Dies ist ein absolut * schrecklicher * Ansatz. Sicher können Sie keine 39 Bit von einem CRC-32 wiederherstellen. Der Platz, den Sie für Brute-Force benötigen, wird jedoch auf 7 Bit reduziert :( Es spielt keine Rolle, wie groß Ihr kryptografischer Hash ist, alles, was größer als der Eingabebereich ist, erweitert die Suche nicht.
KurtWegner
2020-03-28 04:12:32 UTC
view on stackexchange narkive permalink

Ergänzen Sie die vorherigen Vorschläge. Wie wäre es mit SHA-3 (das anscheinend erst 2015 offiziell war, später als diese Diskussion), bei dem der Kartennummer ein händlerspezifischer geheimer Schlüssel vorangestellt wird, um die Hashes händlerspezifisch zu machen.

Das einfache Voranstellen eines geheimen Schlüssels an die Nachricht war für SHA-1 und SHA-2 aufgrund ihrer Schwäche bei der Längenerweiterung unsicher. Dies ist bei SHA-3 nicht der Fall, das von Natur aus gegen Längenverlängerungsangriffe resistent ist. Wie hier erklärt, könnte man SHA-3 sogar für die MAC-Berechnung verwenden, indem man der Nachricht einfach den Schlüssel voranstellt.

Natürlich bleibt das Problem, wie die geheimen Schlüssel sicher gespeichert werden . Ich habe keine Erfahrung mit der Zahlungskartenbranche. Ich bin gerade auf diese Frage gestoßen und fand sie interessant. Ich würde gerne einige Kommentare von erfahreneren Benutzern zu den Problemen erhalten, die mit dem Umgang mit Kartennummern (und ihrem relativ kleinen Suchraum) bei Verwendung dieses Ansatzes zu tun haben.

Brian
2014-07-16 23:10:03 UTC
view on stackexchange narkive permalink

Sie dürfen es nicht gemäß den hier definierten PA-DSS-Standards speichern: https://www.pcisecuritystandards.org/documents/pa-dss_v2.pdf

Darin heißt es :

1.1 Speichern Sie keine vertraulichen Authentifizierungsdaten nach der Autorisierung (auch wenn diese verschlüsselt sind): Zu den vertraulichen Authentifizierungsdaten gehören die Daten, die in den folgenden Anforderungen 1.1.1 bis 1.1.3 aufgeführt sind.

In der nebenstehenden Spalte heißt es:

Wenn diese Zahlungsanwendung vertrauliche Authentifizierungsdaten speichert, stellen Sie sicher, dass die Anwendung nur für Emittenten und / oder Unternehmen bestimmt ist, die die Ausgabe von Diensten unterstützen

Ich gehe davon aus, dass Sie kein Emittent oder Unternehmen sind, das die Ausgabe von Diensten unterstützt. Beachten Sie, dass die Target Corporation kürzlich gehackt wurde und Kreditkarteninformationen in Echtzeit und von Servern gestohlen wurden, die die Daten nicht durchgehend verschlüsselt haben. Nach meinem Verständnis wird es korrigiert und sicherer gemacht. Ehrlich gesagt, speichern Sie es nicht Zeitraum. Selbst wenn Sie SHA512-Hash verwenden, ist Ihre Implementierung möglicherweise fehlerhaft. Mit den besten Gegenmaßnahmen möchte ich nicht am Ende einer Klage stehen.

Bearbeiten:

Technisch ist dies in Abschnitt 2.3 von PA-DSS v2.0 zulässig. Aber tu es nicht.

In Abschnitt 3.4 von PCI-DSS v3.0 finden Sie spezifische Anleitungen zum Speichern von PAN-Hashes. Es ist widerwillig und mit Vorbehalten erlaubt.
@Xander: Ja, ich hatte gehofft, das nicht zu sagen und nur Carte Blanche zu sagen, tu es nicht :)
Tatsächlich ist dies zulässig, da die PAN nicht in dieser Liste vertraulicher Daten enthalten ist (siehe Seite 12.). Bei vertraulichen Daten handelt es sich entweder um vollständige Spurdaten, CAV2 / CVC2 / CVV2 / CID- oder PIN-Blöcke. (Haftungsausschluss: Ich bin kein QSA. Fragen Sie Ihren QSA nach Ihrer eigenen Situation.)
@JohnDeters: Ja, aber die PAN ist in Spur 1 und 2 enthalten. Es ist wirklich ein schlechter Absatz. Sie sollten es nicht zulassen
Es gibt keine "SHA512-Verschlüsselung". Hashing und Verschlüsselung sind sehr unterschiedlich und es ist gefährlich, sie zu verwirren.
@staticx, Die Spezifikation gibt eindeutig an, dass es sich bei der PAN genau wie beim Namen des Karteninhabers um Kundendaten handelt und nicht in der Spalte für vertrauliche Daten. Trackdaten sind sensibel, weil sie CVV enthalten, nicht weil sie PAN enthalten.
@JohnDeters: Ich verstehe das. Mein Punkt ist, dass es lächerlich ist, die Spuren mehr als die PAN zu schützen
@staticx, es ist nicht lächerlich. Die CVV-Daten in der Spur werden als "Beweis" dafür verwendet, dass der Magnetstreifen für die Transaktion vorhanden war, im Gegensatz zur CVV2-Nummer, die nur anzeigt, dass ein Mensch ihn gesehen hat. Banken weisen Card Present-Transaktionen ein geringeres Risiko zu, sodass der Einzelhändler bei der Verarbeitung einen reduzierten Zinssatz erhält. Wenn Sie CVV2 beibehalten, kann ein Einzelhändler Betrug begehen.
@JohnDeters: Ja, ich verstehe das alles. Ich habe den PA-DSS-Prüfungsprozess durchlaufen. Jeder kann eine Kreditkarte nur für Track 1 unter Verwendung des Kundennamens, der PAN und des Ablaufdatums erstellen. Beides gilt nicht als sensible Daten. Daher können Sie mit diesen Daten problemlos eine Kreditkarte erstellen. Ich habe meine eigenen zum Testen erstellt, es ist nicht so schwer. Mein Punkt ist, dass sie weniger Risiko für die Beibehaltung der PAN als für die Beibehaltung der vollständigen Trackdaten zuweisen.
@staticx, nein, Sie können keine gültige Spur 1 erstellen, die die Autorisierung besteht, es sei denn, Sie haben die richtige CVV. Die Bank wird es ablehnen. Die PAN ist weniger riskant zu halten als die CVV.
@JohnDeter: Ich habe meine eigenen Karten erstellt. Es ist nicht so schwer. Alles was Sie brauchen ist Track eins. Es ist einfach zu generieren. Ich habe sie die ganze Zeit zum Testen erstellt. Und sie würden Autorität weitergeben
@JohnDeters: Die diskretionären Daten, in denen der CVC1 gespeichert ist, sind völlig optional. Sie können dort Nullen setzen. CVC1 dient als eine Art Prüfsumme, um sicherzustellen, dass die Daten nicht manipuliert wurden und dies in den diskretionären Daten enthalten ist. Viele Emittenten ignorieren diese diskretionären Daten, da sie gut diskretionär sind. CVC2, das sich normalerweise auf der Rückseite der Karte befindet, ist nur für Augen gedacht.
Andrew Hoffman
2014-07-17 23:13:34 UTC
view on stackexchange narkive permalink

Wenn Sie es tun wollen, fügen Sie eine Art Verschleierung hinzu. Ich habe mir nur Downvotes garantiert, aber die Verschleierung ist nicht wertlos, wie manche behaupten werden.

Wenn Sie davon ausgehen, dass das System bekannt ist, gibt es keinen Wert. Aber wenn das System nicht bekannt ist, gibt es absolut Wert. Eine IV, die verwendet wird, um zu "pfeffern", wie Xander es ausdrückte, wäre eine Form der Verschleierung, ohne die Kollisionen zu erhöhen und die Fähigkeit zur Abfrage aufrechtzuerhalten.

Ein Pfeffer wäre jedoch keine sehr effektive Verschleierung , es sei denn, der Pfeffer ist groß genug, um nicht in angemessener Zeit erraten zu werden. 100 zufällige Bytes könnten übertrieben sein, aber es gibt keinen Grund, nicht groß zu werden.

Eine andere Sache, die eine effektive Verschleierung sein könnte, wäre, nicht anzunehmen, dass sowohl der Pfeffer als auch die Nachricht gleichzeitig erreicht werden Wenn Sie die Hashes in einer nächtlichen Charge regelmäßig aufwärmen (wobei Sie nachverfolgen, wie viele Runden Sie haben), benötigen Sie eine weitere Information - wie viele Runden oder wie die Runden berechnet werden.

Denken Sie daran dass ich das nicht für eine gute idee halte, denke ich hier nur laut nach. Wenn Ihre Umgebung für Kreditkarten sicher genug ist, würde ich sie nicht nur nicht hashen, sondern sie auch in einer Tabelle speichern, die für die schnellste Suchleistung ausgelegt ist.

Überprüfen Sie die akzeptierte Antwort. Es wird ein Zufallszahlengenerator verwendet, der nichts über die Kartennummer preisgibt.
Oh, nun, ich habe das alles gestern gelesen und es gab keinen Kontext oder Anwendungsfall, der alles verändert.
@FloatingRock: Ihre Schwachstelle ist der Transit der Karte von der Anwendung nach Braintree. Außerdem gibt es eine Schwachstelle am Swipe Reader zum PC zur Anwendung. Es gibt Lösungen, die End-to-End verschlüsseln, aber Geld kosten.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...