Question:
Hachage d'un numéro de carte de crédit pour l'utiliser comme empreinte digitale
FloatingRock
2014-07-16 20:23:13 UTC
view on stackexchange narkive permalink

Transforming the credit card number into a fingerprint

Quelle est la meilleure façon de hacher un numéro de carte de crédit afin qu'il puisse être utilisé pour la prise d'empreintes digitales (c'est-à-dire que la comparaison de deux hachages vous permettra de savoir si les numéros de carte correspondent ou non) ?

Idéalement, je suis à la recherche de recommandations sur le hachage + sel qui pourrait convenir à ce cas d'utilisation. Le hachage identifierait de manière unique un numéro de carte particulier. Vous pouvez utiliser cet attribut pour vérifier si deux clients qui se sont inscrits avec vous utilisent le même numéro de carte, par exemple. (puisque vous n'auriez pas accès aux numéros de carte en texte brut)

Fingerprints match

Pour donner un peu de contexte, consultez la documentation de l'API Stripe et recherchez empreinte digitale . C'est là que j'ai entendu parler de ce concept pour la première fois. Les informations de la carte de crédit seront stockées sur une machine sécurisée (quelque part dans le back-end de Stripe) qui n'est pas accessible par le client, et l'API renvoie l'empreinte digitale afin de permettre au consommateur de l'API de faire des comparaisons (par exemple pour répondre à des questions telles que cette carte a-t-elle déjà été utilisée? ).

Clarifions celle-ci, car je sais que vous allez demander: Je n'essaye pas de la reproduire. Je suis simplement curieux de comprendre comment cela pourrait être mis en œuvre

Allez-vous les vérifier en quelque sorte comme un mot de passe, ou devrez-vous pouvoir interroger? Le salage casserait directement la capacité d'interroger.
Parce que si vous voulez le protéger contre les devinettes bruteforce comme vous le feriez pour un mot de passe, vous devez le traiter comme un mot de passe, sauf avec des numéros CC à la place. CC hash et salt associés à cet utilisateur. Un bon hachage lent avec étirement, comparaison sécurisée, etc.
Donc sel + hash * ne * fonctionnera pas, car les sels sont uniques. Ainsi, deux numéros de carte identiques, une fois salés, produiront des hachages différents, et vous ne pourrez pas déterminer que le numéro de carte correspond à un hachage salé préexistant du même numéro de carte, car les sels seront différents.
-1
J'ai tendance à être d'accord avec [la réponse de u2707] (http://security.stackexchange.com/a/63251/12) et si vous ne pouvez pas stocker les numéros de carte de crédit en toute sécurité, je ne pense pas qu'il soit raisonnable de stocker des hachages non plus . Je ne peux pas suggérer de faire cela à vos clients.
Les rediriger vers paypal?
@Xander: Réutilisez le même sel. Le sel est normalement stocké non chiffré. À des fins de comparaison de toute façon, récupérez-le simplement et recommencez en utilisant le même sel, vérifiez s'ils correspondent. Cela étant dit, je ne conserverais aucun numéro de carte de crédit.
@staticx Ce n'est pas un sel, c'est un poivre, et ce n'est pas particulièrement précieux du point de vue de la sécurité lorsque vous essayez d'empêcher le hachage de hachage, car vous n'avez encore besoin de calculer qu'un seul ensemble de hachages pour récupérer toutes les valeurs.
@Xander: Intéressant, jamais entendu ce terme auparavant. J'ai passé un audit PCI en utilisant un sel, je veux dire du poivre, il y a environ 2-3 ans.
@staticx C'est une sorte de terme ringard que je connais, mais comme par définition un sel doit être unique au monde, une valeur qui est utilisée plus d'une fois n'est pas admissible.
@Xander: Je préfère personnellement un jeton à sens unique.
@staticx donc pour donner un peu de contexte à cela, consultez la [documentation de l'API Stripe] (https://stripe.com/docs/api) et recherchez `fingerprint`. C'est le même concept. Les informations de la carte de crédit seront stockées sur une machine sécurisée non accessible par le client (consommateur d'API), mais l'empreinte digitale est retournée afin de lui permettre de faire des comparaisons.
Alors, comment le coffre est-il crypté et comment la carte est-elle cryptée à l'intérieur du coffre?
pas tout à fait lié à la sécurité, mais votre objectif est-il de faire en sorte que 2 clients ne puissent pas utiliser le même CC? J'imagine rapidement quelques situations où 2 comptes distincts utilisent le même CC: un père et un fils qui jouent tous les deux à des jeux vidéo, et le père utilise son CC pour payer les jeux du fils à son propre compte; un couple marié qui a des comptes Amazon séparés pour séparer leurs collections Kindle, mais qui utilise une carte de crédit pour les deux achats; Une entreprise qui a besoin de plusieurs organisations Office365 distinctes, mais qui les paie avec la carte de crédit de l'entreprise. évitez de rendre des choses uniques qui pourraient ne pas l'être.
@NateKerkhofs c'est pour que le client (le consommateur de l'API) puisse décider quoi faire dans chaque scénario. Si vous souhaitez regrouper des clients qui utilisent le même CC, vous aurez besoin d'une sorte d'empreinte digitale pour identifier le jeton - ce que Stripe fournit. Vous pouvez faire ce que vous voulez avec cette empreinte digitale.
Dans votre dernière édition, ce n'est pas parce que quelqu'un le fait que demain, ce sera mal vu. De plus, que faire si le serveur Stripe est en panne? Voulez-vous vraiment être lié à ce service?
J'ai * utilisé * Hash (fixed_salt_or_pepper + PAN) pour indexer les cartes sur liste noire, et cela a réussi l'audit PCI (et FISMA je crois). Cependant, nous n'avons pas utilisé ce mécanisme pour stocker les cartes utilisables des clients.
@staticx Si le serveur de Stripe est en panne et que vous les utilisez pour vos services marchands, vous ne pouvez pas traiter les cartes / transactions de toute façon, donc ce n'est pas pertinent si vous dépendez d'eux pour cette fonction également.
Huit réponses:
Xander
2014-07-17 00:06:37 UTC
view on stackexchange narkive permalink

D'accord, donc s'il s'agit d'une exigence commerciale que vous devez respecter (vérifiez si une carte existe déjà dans le système), voici comment je procéderais.

Premièrement, PCI-DSS permet de stocker un PAN (le numéro de compte principal ou le numéro de carte de crédit) sous forme hachée en utilisant une "cryptographie forte" et ils recommandent (mais ne nécessitent pas) qu'un le sel doit également être utilisé. PCI-DSS v3 § 3.4 (lien PDF) La raison est d'empêcher la capacité d'une partie malveillante qui récupère le hachage de déterminer le PAN qui a été utilisé comme entrée pour le hachage.

Deuxièmement, votre projet de stocker ceci dans un système séparé et sécurisé et de l'exposer uniquement via une API est une bonne mesure de défense en profondeur. Si je mettais en œuvre cela, je ne lui demanderais pas de renvoyer un hachage au système principal, je prendrais simplement le hachage comme paramètre pour l'appel d'API et ferais en sorte que l'API renvoie «true» ou «false» selon que le hachage existe déjà dans le système ou non.

Pour la fonction de hachage, la clé pour empêcher la récupération des entrées (comme requis par PCI-DSS) est de choisir un algorithme qui vous permet de faire le processus difficile en termes de calcul, donc la tâche de forcer brutalement l'espace d'entrée relativement petit des PAN valides est raisonnablement lente. SHA-512, suggéré par une autre réponse, n'est pas cet algorithme. En regardant la matrice de test pour le hachage de hachage fournie par hashcat.net, la machine la plus rapide de leur matrice peut calculer près de 2 milliards de hachages SHA-512 par seconde. Avec un espace d'entrée estimé à environ 30000000000000 de cartes **, cela signifie que non salées, vous pouvez calculer le SHA-512 de chacun de ces PAN en un peu plus de 4 heures et avoir les numéros de carte pour toujours dans la base de données, si jamais être volé.

Nous avons donc besoin d'une fonction de hachage lente, mais la définition de la lenteur change tout le temps à mesure que les ordinateurs deviennent plus rapides et que la technologie évolue. Cela signifie qu'une fonction de hachage sécurisée sera une fonction avec un facteur de travail réglable, de sorte qu'au fil du temps, vous pouvez augmenter l'effort de calcul requis pour calculer le hachage d'une entrée donnée. Il existe plusieurs algorithmes candidats qui répondent à ces critères, notamment PBKDF2, bcrypt et scrypt. Le consensus général pour le hachage de mot de passe est bcrypt, et c'est ce que je suggérerais ici. Pour le coût, définissez-le aussi haut que votre application le permet. Ce n'est probablement pas quelque chose que vous calculerez très fréquemment (j'imagine que, en fonction de votre application, vous allez regarder x hachages par minute ou heure ou jour plutôt que par seconde) et le plus élevé le coût, plus ce sera difficile pour un adversaire qui capture le hachage à la force brute.

** Mon estimation est basée sur un numéro de compte à 9 chiffres, un chiffre de contrôle calculable qui n'augmente pas la complexité et un WAG de 30000 numéros d'identification bancaire actifs (les 6 premiers chiffres de la carte) basé sur une liste que j'ai trouvée.

Je pense que vous êtes trop optimiste. Bcrypt résiste très bien aux FPGA, et je suppose que les 4 derniers chiffres sont connus de l'attaquant.
@CodesInChaos Eh bien, dans l'ensemble, mon conseil de ne pas faire cela du tout dans la pratique tient toujours. En théorie cependant, si vous suivez PCI, les numéros de carte tronqués sont bien séparés des hachages et une violation de l'un ne compromet pas l'autre. En pratique ... * Shrug. * Dans une implémentation théorique cependant, face au manque de résistance aux attaques basées sur FPGA que vous avez évoqué, suggérez-vous que le scrypt est une meilleure option?
Les numéros de carte de crédit ne sont pas sécurisés en premier lieu de toute façon. La plupart des systèmes de numéros de série pour les jeux ont plus d'entropie que cela. Quand allons-nous nous en débarrasser?
@CodesInChaos que feriez-vous? (si ne rien faire n'était pas une option)
@CodesInChaos Comme BCrypt utilise un sel différent à chaque fois, vous ne pourrez pas vraiment comparer les hachages résultants. À moins, bien sûr, que vous n'utilisiez le même sel, ce qui ne me semble pas très cryptique.
John Downey
2014-07-17 19:08:33 UTC
view on stackexchange narkive permalink

Je ne peux pas commenter la façon dont Stripe fait cela, mais je peux vous dire exactement comment Braintree le fait (car c'est là que je travaille). Si je devais deviner, Stripe utilise probablement une méthode similaire.

Dans l'API Braintree, nous proposons un identifiant de numéro unique pour une carte de crédit. Cet identifiant est un jeton opaque aléatoire qui sera toujours le même pour le numéro de carte stocké dans notre système. La valeur de départ de ce numéro est différente selon les marchands dans notre système, vous ne pouvez donc pas les comparer entre les marchands.

Lorsqu'une nouvelle carte arrive, nous la recherchons en la comparant à une colonne hachée + salée. S'il correspond à cette colonne existante, nous savons que nous pouvons renvoyer le même identifiant de numéro unique. S'il ne correspond à aucun enregistrement existant, nous utilisons un générateur de nombres pseudo-aléatoires cryptographiquement sécurisé pour créer un nouvel identifiant de numéro unique et nous assurer qu'il n'est pas en conflit avec un existant.

De cette façon, le hachage + La valeur salée ne quitte jamais notre backend, mais nous pouvons toujours fournir un moyen pour un marchand d'identifier de manière unique les cartes de crédit stockées.

Brillant! @Xander, Je serais ravi d'entendre vos commentaires sur les bits de sécurité (et n'importe qui d'autre d'ailleurs).
@FloatingRock Mon opinion est que cela étend fondamentalement la méthode que j'ai décrite en (a) épinglant le PAN avant le hachage, puis (b) en stockant un jeton (ou une empreinte digitale) supplémentaire unique et généré aléatoirement à côté du hachage. Vous avez toujours les exigences pour sécuriser fortement le calcul de l'application et de la base de données et le stockage des hachages et des jetons, mais vous pouvez ensuite renvoyer le jeton à l'application frontale pour qu'il le conserve, et cela ne révèle aucune information sur la carte à laquelle il est associé. . C'est assez agréable en ce sens qu'il vous permet de décharger des fonctions vers le front-end sans aucune exposition supplémentaire aux données de la carte.
+1 J'ADORE la façon dont le jeton est complètement séparé, car il n'est pas du tout dérivé du PAN.
@Xander: C'est mieux car vous ne stockez pas du tout le PAN haché et salé. Il est réexécuté à chaque fois que la transaction se produit. Le seul problème que je vois avec ceci est ou Stripe est que vous devez être en ligne 24/7. Si la connexion Internet tombe en panne, vous ne pouvez pas traiter les cartes de crédit. J'écrivais le code de traitement des cartes de crédit pour les applications de stationnement et de nombreux garages de stationnement sont entièrement automatisés sans caissier. Nous avons dû concevoir une méthode pour stocker en toute sécurité les cartes de crédit hors ligne jusqu'à un certain montant. Une fois qu'il est revenu en ligne, il a vidé les transactions.
À l'époque, et je pense toujours, c'était une situation moins risquée car elle ne stockait pas les cartes pour toujours et la base de données a été supprimée en toute sécurité une fois qu'elle a été vidée sur le serveur maître qui n'a jamais conservé les informations de la carte. Cela nous obligeait à placer un PC durci dans la machine créée par ADAM appelée UNO avec un logiciel spécial comme intermédiaire.
@staticx Je pense que vous avez manqué un peu. "Quand une nouvelle carte arrive, nous la recherchons en la comparant à une colonne hachée + salée" Le PAN haché * est * stocké, par Braintree, et je suppose Stripe. Le PO veut savoir comment fonctionne cette mise en œuvre.
@Xander: Ensuite, il y a encore un point faible. Il décharge le stockage vers un autre service en espérant qu'il est sécurisé.
@staticx vrai, le backend aurait certainement besoin d'être sécurisé (et conforme PCI). La clé est que l'empreinte digitale partagée avec l'utilisateur final ne peut pas être utilisée pour dériver la _période_ PAN. (plus comme une virgule ... sauf si bien sûr le backend a été compromis).
@FloatingRock: Oui, la corrélation doit se produire dans leur base de données uniquement car il n'y a pas de moyen de fournir l'empreinte digitale ou le numéro unique et de récupérer un numéro de carte. Ce serait royalement stupide. Je pense que vous augmentez votre risque en stockant le numéro de carte n'importe où. PCI ne va pas assez loin à mon avis pour empêcher le stockage. Il devrait carrément refuser la possibilité de stocker le numéro n'importe où. Cela entraînerait un léger inconvénient, mais pas aussi grave que ce qui est arrivé récemment à Target ou à d'autres détaillants.
@staticx qui sonne bien en théorie. Dans la pratique cependant, il existe des besoins légitimes qui nécessitent le stockage de ces informations. La facturation récurrente (ou les abonnements), par exemple, nécessite le stockage du numéro de carte.
@FloatingRock: Il est très, très difficile de stocker en toute sécurité les informations de carte de crédit. En fait, il a été annoncé il y a cinq ans que 130 millions de numéros de carte de crédit avaient été volés à de grandes sociétés de vente au détail et de financement qui disposent probablement de beaucoup plus de ressources que vous pour sécuriser ces données. Je comprends parfaitement la volonté de faciliter facilement les paiements récurrents. Cependant, réfléchissez et comprenez le risque lié au stockage des numéros de carte de crédit avant de décider de le faire.Si vous décidez que vous devez stocker les numéros de carte, je vous recommande de faire appel à un expert en sécurité ayant fait ses preuves.
En termes de remboursement, vous pouvez en théorie stocker le numéro de carte tronqué haché avec un sel unique avec le nom de la personne afin que (comme lorsque vous retournez quelque chose chez Target), il corresponde au hachage sécurisé si la carte est présentée à nouveau. Cela ne dépendrait pas de Stripe et vous n'auriez pas à stocker le PAN complet même si vous devez toujours protéger la version tronquée. Il existe différentes astuces que vous pouvez faire, le fait est qu'une fois que vous décidez de le stocker n'importe où, il y a un risque commercial que de simplement le transmettre au processeur.
@staticx oh très certainement. Je n'essaierais pas de le faire, même avec les conseils d'un expert. Je préfère de beaucoup avoir quelqu'un qui est pleinement qualifié pour le faire, et même alors embaucher quelqu'un pour tenter une effraction. Je ne faisais que souligner un exemple de cas où il existe une justification commerciale légitime.
Par curiosité, qu'est-ce qui vous a incité à utiliser un PRNG pour générer le jeton, au lieu de dire un PK auto-incrémenté, qui n'aurait pas besoin de presque autant de puissance de calcul et de recherches dans la base de données pour garantir l'absence de collisions?
@RainFromHeaven, nous voulions que la valeur renvoyée soit complètement opaque et ne donne aucune information. Si vous utilisez un champ auto-incrémenté, cela pourrait révéler le nombre relatif de cartes stockées et la vitesse de croissance
Pour tous ceux qui commentent les implications PCI de ceci. Je suis d'accord qu'une version hachée d'un PAN est inversée de manière triviale dans le PAN complet si elle est divulguée (juste à cause du petit domaine des PAN). Braintree est un fournisseur de services PCI de niveau 1 et le hachage des PAN à cette fin est inclus dans notre audit PCI annuel sur site. La valeur ajoutée de l'utilisation d'un service comme Braintree est de contribuer à réduire la charge PCI des marchands que nous soutenons. C'est pourquoi nous proposons un moyen d'identifier de manière unique les cartes sans avoir à stocker le hachage du côté des commerçants.
@JohnDowney par 'Quand une nouvelle carte arrive, nous la recherchons en la comparant à une colonne hachée + salée', vouliez-vous dire quand une nouvelle carte arrive, vous la comparez à toutes les cartes de crédit que vous avez déjà? Comme ils sont prévus, vous devez les essayer un par un?
@Alfred oui, mais les index de base de données ne le rendent pas aussi effrayant qu'il y paraît
u2702
2014-07-16 21:04:16 UTC
view on stackexchange narkive permalink

Le hachage des numéros de carte de crédit ne remplace pas la sécurisation des données. Si votre système n'est pas suffisamment sécurisé pour stocker les numéros de carte de crédit bruts, il n'est pas suffisamment sécurisé pour stocker les hachages CC.

Même chose pour tout ce qui est d'une taille fixe et d'un jeu de caractères limité: date de naissance, numéro de téléphone , zip, etc.

Les cartes de crédit sont toutes à 16 chiffres et bien que 10 ^ 16 semble être un grand nombre, c'est assez simple pour les ressources de calcul. Si j'ai votre table de hachages CC #, je peux facilement l'attaquer avec une table arc-en-ciel et obtenir une liste complète des cartes de crédit. Le salage des valeurs avant le hachage rend la recherche impossible.

Toutes les valeurs CC possibles: quelque chose de moins de 10 ^ 16.

À titre de comparaison, imaginez que vos utilisateurs ont utilisé un mot de passe raisonnable de 8 caractères avec un Sel de 20 octets: 62 ^ 28.

(Si j'étais votre auditeur PCI, je considérerais que le hachage des cartes de crédit équivaut à stocker les numéros de carte eux-mêmes.)

Un ajout et un point pédant. Le point pédant: certains numéros de carte de crédit ont 15 chiffres, pas 16. Ce n'est pas que cela change beaucoup votre réponse, mais je voulais le noter. De plus, vous n'auriez pas à forcer brutalement tout l'espace. Le premier ensemble de chiffres dans un numéro CC est l'un des rares préfixes connus, et le dernier est un chiffre de contrôle, donc l'espace des nombres valides possibles est un peu plus petit.
Je t'ai eu. Mise à jour de la question pour clarifier mes intentions
@Xander: Oui, et c'est plus petit que les gens ne le pensent, car le numéro de carte entier doit passer l'algorithme de Luhn.
Pas encore assez de représentants pour commenter, mais cela concerne principalement les réponses précédentes suggérant sur 10 ^ 16 comme le nombre "maximum" de "hasard" - ce n'est pas vraiment proche de 10 ^ 16, puisque sur les 16 chiffres qui composent un numéro de carte de crédit, seuls les chiffres 7-15 (inclus) identifient le compte - les autres identifient le type (mastercard, visa, etc.), l'émetteur (banque XXX), le type spécifique de carte (IE Delta gold rewards) . Enfin, il y a une "somme de contrôle" qui signifie que vous pouvez (rapidement pour un ordinateur par rapport au calcul d'un hachage) éliminer un autre chiffre si cela ne correspond pas, donc de manière réaliste, vous êtes l
"quelque chose de moins de 10 ^ 16" - oui, certainement quelque chose de plus petit que 10 ^ 16, trop paresseux pour faire le calcul.
John Deters
2014-07-17 05:31:09 UTC
view on stackexchange narkive permalink

La réponse vous décevra: si un service / oracle / hash peut vous dire si un numéro d'entrée est dans le fichier, il peut être brisé par une très petite quantité de force brute.

Considérez que dans une grande partie du pays, les cartes de crédit sont émises par relativement peu de banques dans leur région géographique. Vous pouvez facilement connaître les numéros BIN de la plus populaire de ces banques. Supposons que vous ayez un reçu d'un magasin de Memphis et qu'il indique VISA **** 1234. Il y a environ 20% de chances que ce soit l'un des dix BIN différents appartenant aux plus grandes banques de la région de Memphis. C'est 10 ^ 1 suppositions pour les six premiers chiffres. Ensuite, vous connaissez les 4 derniers, car ils sont imprimés sur le reçu. Cela fait maintenant seulement 10 ^ 1 suppositions qui couvrent 10 des 16 chiffres. Sur les six chiffres restants, itérez sur 5 et calculez le dernier en utilisant Luhn. C'est 10 ^ 6 tests qui donneront un numéro de compte valide 20% du temps.

Tout ce que vous avez à faire pour tester un nombre est de parcourir le service 100 000 fois. Peu importe si le service utilise un hachage ou un cryptage ou une baguette magique pour protéger les numéros de compte, du moment qu'il vous indique si votre entrée correspond ou non.

Vous pouvez noter que cela ne fonctionne qu'environ 20% du temps. Considérez que le gars qui a volé Target a pris 40 millions de numéros de compte, et il ne pouvait pas les vendre tous, car il n'y avait pas assez d'escrocs dans le monde pour en acheter autant. 20% de ce montant est de 8 millions, et il n'en a probablement pas vendu autant non plus. Donc 20%, c'est assez bon pour un attaquant.

J'ai mis à jour la question avec une pensée ... beaucoup d'entre vous considèrent cette pratique comme peu sûre, alors peut-être qu'une divulgation responsable à Stripe est en ordre.
Et Braintree. Mais honnêtement, personne ne s'intéresse à cette vulnérabilité, car la supprimer tuerait nécessairement la justification commerciale.
Damon
2014-07-17 18:38:25 UTC
view on stackexchange narkive permalink

tl; dr:
Il n'est pas possible de faire une telle chose de manière vraiment sécurisée, mais cela peut être fait d'une manière "probablement assez bonne" pour être utilisable et acceptable .

Vos options sont essentiellement une forme de stockage crypté (avec le risque que les clés de cryptage soient volées, car elles doivent être présentes pour le décryptage), ou quelque chose impliquant du hachage, avec les problèmes bien connus du hachage mots de passe (un numéro de carte de crédit est fondamentalement un «mot de passe»).

Je mettrais en œuvre cela comme un système à deux niveaux où le premier niveau serait un simple CRC32 et le second serait plusieurs fois fonction de hachage sécurisée itérée. Oui, CRC32 n'est pas un hachage cryptographiquement sécurisé, mais cela n'a pas d'importance dans ce cas particulier, puisque le CRC n'est pas le maillon faible.
Si l'idée d'utiliser un non-cryptographiquement- L'algorithme sécurisé vous fait trop peur, vous pouvez toujours remplacer le CRC par un algorithme cryptographique secore et n'utiliser que par exemple les 32 bits les moins significatifs (ou 16, pour une plus grande marge) du hachage résultant.

La raison de cette approche est que la plage d'entrées possibles ne couvre que 39 bits environ [1] . Il est pratiquement impossible de hacher cet espace de clés de manière vraiment sécurisée tout en gardant le système opérationnel pour l'utilisation prévue.
Une attaque par force brute sur un espace de clés de 39 bits est non seulement théoriquement faisable, mais en fait assez trivial - à moins que chaque opération est extrêmement coûteuse.

La principale menace contre laquelle vous devez vous défendre est le vol de votre base de données, suivi de forcer brutalement vos hachages pour récupérer des numéros de carte valides. La prochaine meilleure chose qu'un attaquant pourrait faire serait d'interroger en ligne si un numéro inconnu qui hache de manière identique à un numéro soumis aléatoirement a déjà été utilisé, ou de demander si un numéro valide déjà connu a été utilisé (ni l'un ni l'autre n'est très utile, cependant!).

Les cartes de crédit sont généralement valables 5 ans, donc pour que le système soit sécurisé, il doit supporter au moins 5 ans de force brute. En d'autres termes, le travail effectué pour une seule vérification doit être si complexe sur le plan informatique qu'une machine de craquage multi-GPU dédiée ne peut pas effectuer plus de 2 ^ 39 / (5 * 365 * 86400) = 3486,5 vérifications par seconde.

Si l'on prend le chiffre bien connu de 348 milliards par seconde de 2012, la seule approche vraiment sécurisée devrait donc stocker la valeur d'avoir haché au moins 100 millions de fois. En tenant compte de la loi de Moore, ce serait 200 millions maintenant, et nous n'envisageons même pas la possibilité que quelqu'un possède 2 ou 3 de ces machines (ou peut-être 10).

Cependant, ceci encore ne prend pas en compte le fait que les banques sont par nature stupides et vont simplement incrémenter l'avant-dernier chiffre pour un nouveau numéro valide (et mettre à jour le chiffre de contrôle). Toutes mes cartes de crédit émises au cours des 20 dernières années ont eu le même numéro à l'exception de l'avant-dernier chiffre incrémenté de 0, 1, 2, 3, ...
Ce qui signifie que la planification sur 5 ans toujours ne suffit pas . Une personne connaissant un numéro de carte de crédit expiré peut dériver le numéro valide de la carte d'abonné. Il faut donc plutôt prévoir quelque chose comme 30 ans, pas 5 ans. Je vais laisser extrapoler la loi de Moore à 20-30 ans supplémentaires pour faire mes devoirs.

En conclusion, pour que le système soit vraiment, vraiment sécurisé , votre serveur devrait effectuer le l'équivalent d'un billion de hachages (ou plus) par vérification, ce qui à un taux de, disons 10 millions par seconde pour une implémentation CPU typique, prendrait plus d'une journée. En d'autres termes, le système est complètement inutilisable pour son objectif désigné .

Quelque chose de plusieurs ordres de grandeur plus rapide est nécessaire. La plupart des requêtes seront des requêtes négatives, et un hachage simple et rapide pourrait être utilisé pour éliminer 99,9% de tous les négatifs, si seulement cela ne rend pas la sécurité déjà faible encore plus faible. C'est là que CRC32 entre en jeu.

Si les CRC32 de deux numéros de carte de crédit ne correspondent pas , il est garanti que les numéros ne sont pas les mêmes. La plupart du temps, ce sera le cas, et vous pouvez immédiatement retourner "Non!". Vous pouvez sauter 99,9% du travail sans rien dévoiler.
Si les CRC correspondent , cela peut être un succès, mais il y a un risque de collision de hachage. Maintenant, le hachage cryptographique sécurisé (qui aurait au moins 160, mieux 256 bits) est calculé et comparé. La probabilité d'une collision est désormais négligeable. Si le hachage correspond, il est certain que le nombre correspond.

CRC32 contient 32 bits d'informations. Il est impossible de restaurer 39 bits d’information à partir de 32 bits, quelles que soient les ressources de calcul dont vous disposez. Par conséquent, le CRC est sûr à utiliser dans ce cas (ou du moins, il n'est pas moins sûr que toute autre chose).

Comme l'a souligné Ben Voigt, il est de bien sûr encore possible de deviner les informations qui ne peuvent pas être restaurées, et 7 bits à deviner ne sont pas terrible (concaténer la date d'expiration fera 15 bits). C'est vrai, mais vous ne pouvez pas faire grand-chose à ce sujet.

Qu'en est-il du CRC et de la sécurité de toute façon? Le CRC n'est pas sécurisé sur le plan cryptographique. Il est relativement facile de falsifier les bits pour obtenir la sortie souhaitée (pas de problème ici, ce serait avec les connexions), et la fonction peut être inversée de manière triviale (4 recherches de table, plus quelques décalages et xor) vers une entrée 32 bits, un problème un peu plus important. Heureusement, mais ce modèle de bits n'a pratiquement aucune valeur car ce n'est pas un nombre valide, ni un sous-ensemble d'un modèle de 39 bits qui pourrait être un nombre valide (autrement que par pure coïncidence).

Forcer brutalement l'espace de touches complet de 39 bits est plus simple que d'essayer de jouer des tours sur le CRC, car, malheureusement, c'est assez facile et rapide: une implémentation SSE4.2 utilise environ un demi-cycle par octet (donc, 2 cycles par hachage), ce qui signifie qu’un ordinateur de bureau pourrait faire l’espace de clés complet en une seconde ou deux (en supposant que les clés sont à comparer avec toutes les tailles en L1).

La recherche exhaustive révélerait tous les 39 bits modèles qui ont le même CRC, ce qui signifie qu'ils pourraient éventuellement être des numéros de carte de crédit, et en utilisant l'algorithme de Luhn, l'attaquant peut immédiatement rejeter 9 numéros sur 10 qui ne peuvent pas être valides. C'est mauvais, certes, mais c'est vraiment juste une conséquence de ne pas avoir trop de choix d'entrée et d'avoir un chiffre de contrôle implanté sur le dessus!

Pourtant, le CRC est en fait plus fort dans ce scénario plutôt qu'un algorithme cryptographiquement sécurisé: compte tenu de 2 à 3 milliards de cartes de crédit en circulation dans le monde, le risque de collision avec un hachage de 160 bits se situe entre 1 et 10 20 , et même pas pensez aux chances d'utiliser un hachage de 256 bits. Ce qui signifie que tout résultat lors de votre recherche exhaustive de l'espace de clés 39 bits vous donnera immédiatement le seul et unique numéro de carte valide garanti. Un hit sur le CRC32 ne vous donnera qu'un des nombreux numéros possibles.

Une chose que vous pourriez faire pour échanger un peu de vitesse contre la sécurité serait de jeter davantage d'informations sur le CRC, par exemple, vous pouvez simplement supprimer les 8 ou 16 bits les plus significatifs du CRC, ce qui les ajouterait aux bits qu'un attaquant devra deviner. Bien sûr, cela réduira quelque peu l'efficacité de la taille, mais pas trop drastiquement. Au lieu d'élaguer 99,99% du travail, vous pourriez finir par élaguer 99% ou 98%, ce qui est tout de même très bien.

Le deuxième niveau de vérification, comme indiqué ci-dessus, doit être un hachage cryptographiquement sécurisé qui exécute au moins un million d'itérations, un peu comme il est fait dans un schéma d'étirement de clé (en fait, il a besoin de beaucoup plus que cela , mais le système doit également rester pratiquement utilisable).
Le réalisateur doit ici échanger le risque contre l'utilisabilité, un serveur devrait au moins être capable de traiter quelques dizaines de requêtes par seconde. Les clients / commerçants ne consentiront pas si la recherche d'un numéro prend plusieurs minutes (ou plus), quelles que soient les implications de sécurité. Il n’est pas non plus pratique d’avoir plus ou moins un serveur dédié dédié par marchand.

Comme la correspondance n’est intéressante que sur une base par marchand, on peut utiliser une constante par marchand et stocker les numéros de carte de manière redondante avec un index sur l'identifiant du marchand, qui devrait être dans les pouvoirs de tout système de base de données raisonnable.


[1] Un numéro de carte de crédit comporte 16 chiffres de dont le dernier est une somme de contrôle dérivée des autres (algorithme de Luhn). Le deuxième mais le dernier chiffre est généralement (pas nécessairement, mais généralement) le numéro séquentiel de la carte, commençant à zéro pour la première carte du titulaire du compte, 1 pour le conjoint ou une carte de remplacement, 2 pour la carte suivante par la suite, et ainsi de suite. , les trois premiers chiffres encodent l'émetteur de la carte et la banque, et n'utilisent qu'environ la moitié du nombre possible de combinaisons à 3 chiffres.
Dans l'ensemble, cela nous laisse entre 12 et 13 chiffres décimaux complets d'entropie, ce qui se situe entre un peu plus de 36 bits et 39 bits.

Je recommanderais de concaténer la date d'expiration avec le nombre, car cela rendra cette situation un peu moins misérable. Mes cartes de crédit sont toujours valables 5 ans (je ne sais pas si c'est la règle universelle, mais je suppose que oui), donc l'ajout de la date d'expiration ajouterait 5 * 12 possibilités, ou 5,9 bits (celles-ci sont à peu près gratuites, puisque vous avez de toute façon besoin des données d'expiration dans une transaction!).

Merci Damon. Juste pour clarifier, RE: _ (seule une requête du type "cette personne en particulier a-t-elle utilisé ce numéro avant" serait possible) ._ Si je suis un commerçant utilisant Stripe, je m'en fiche si la carte a été utilisée avec un autre marchand ou non. La portée serait limitée aux cartes utilisées sur un marchand particulier (c'est-à-dire _Me_).
C'est une approche absolument * terrible *. Bien sûr, vous ne pouvez pas récupérer 39 bits à partir d'un CRC-32. Mais l'espace dont vous avez besoin pour la force brute est réduit à 7 bits: (Peu importe la taille de votre hachage cryptographique, rien de plus grand que l'espace d'entrée n'étend la recherche.
KurtWegner
2020-03-28 04:12:32 UTC
view on stackexchange narkive permalink

En complément des suggestions précédentes. Que diriez-vous d'utiliser SHA-3 (qui n'était apparemment pas officiel jusqu'en 2015, après cette discussion) en ajoutant au numéro de carte une clé secrète spécifique au marchand afin de rendre les hachages spécifiques au marchand.

Le simple fait d'ajouter une clé secrète au message n'était pas sûr pour SHA-1 et SHA-2 en raison de leur faiblesse d'extension de longueur. Ce n'est pas le cas avec SHA-3, qui résiste aux attaques d'extension de longueur par conception. Comme expliqué ici, on pourrait même utiliser SHA-3 pour le calcul MAC en ajoutant simplement la clé au début du message.

Bien sûr, le problème de la façon de stocker en toute sécurité les clés secrètes demeure . Je n'ai aucune expérience de l'industrie des cartes de paiement. Je viens de tomber sur cette question et je l'ai trouvée intéressante. J'aimerais recevoir des commentaires d'utilisateurs plus expérimentés sur les problèmes spécifiques au traitement des numéros de cartes (et de leur espace de recherche relativement petit) en utilisant cette approche.

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

Vous ne devez pas le stocker selon les normes PA-DSS définies ici: https://www.pcisecuritystandards.org/documents/pa-dss_v2.pdf

Il déclare :

1.1 Ne pas stocker de données d'authentification sensibles après autorisation (même si elles sont cryptées): les données d'authentification sensibles incluent les données citées dans les exigences 1.1.1 à 1.1.3 suivantes.

Dans la colonne adjacente, il indique:

Si cette application de paiement stocke des données d'authentification sensibles, vérifiez que l'application est destinée uniquement aux émetteurs et / ou aux entreprises prenant en charge les services d'émission

Je suppose que vous n'êtes pas un émetteur ou une entreprise qui prend en charge les services d'émission. Gardez à l'esprit que Target Corporation a récemment été piraté et que les informations de carte de crédit ont été volées en temps réel et à des serveurs qui n'ont pas chiffré les données de bout en bout. Je crois comprendre qu'il est en train d'être rectifié et rendu plus sûr. Franchement, ne stockez pas la période. Même si vous utilisez le hachage SHA512, votre implémentation peut être défectueuse. Avec les meilleures contre-mesures, je ne voudrais pas être au bout d'un procès.

Edit:

C'est techniquement autorisé dans la section 2.3 de PA-DSS v2.0. Mais ne le faites pas.

Il existe en fait des conseils spécifiques sur le stockage des hachages PAN dans la section 3.4 de PCI-DSS v3.0. C'est autorisé, à contrecœur et avec des mises en garde.
@Xander: Oui, j'espérais éviter de dire ça et dire simplement carte blanche ne le faites pas :)
En fait, c'est autorisé, car le PAN ne figure pas sur cette liste de données sensibles (voir page 12.) Les données sensibles sont soit des données de piste complètes, CAV2 / CVC2 / CVV2 / CID ou des blocs PIN. (Avertissement: je ne suis pas un QSA, consultez votre QSA pour votre propre situation.)
@JohnDeters: Oui, mais le PAN est inclus dans les pistes 1 et 2. C'est vraiment un mauvais paragraphe. Ils ne devraient pas le permettre
Il n'existe pas de «cryptage SHA512». Le hachage et le cryptage sont très différents et il est dangereux de les confondre.
@staticx, la spécification indique clairement que le PAN est des données client, tout comme le nom du titulaire de la carte, et n'est pas dans la colonne des données sensibles. Les données de piste sont sensibles car elles contiennent CVV, pas parce qu'elles contiennent PAN.
@JohnDeters: Je comprends cela. Mon point est qu'il est ridicule de protéger les pistes plus que le PAN
@staticx, ce n'est pas ridicule. Les données CVV dans la piste sont utilisées comme "preuve" que la bande magnétique était présente pour la transaction, par opposition au numéro CVV2, qui indique seulement qu'un humain l'a vu. Les banques attribuent moins de risques aux transactions Card Present, de sorte que le détaillant obtient un taux réduit sur leur traitement. Garder CVV2 permettrait à un détaillant de commettre une fraude.
@JohnDeters: Oui, je comprends tout cela. J'ai suivi le processus d'audit PA-DSS. N'importe qui peut générer une carte de crédit Track 1 uniquement en utilisant le nom du client, le PAN et la date d'expiration. Ni l'un ni l'autre ne sont considérés comme des données sensibles. Par conséquent, vous pouvez facilement créer une carte de crédit en utilisant ces données. J'avais l'habitude de créer le mien pour tester, ce n'est pas si difficile. Mon point est qu'ils attribuent moins de risque à la conservation du PAN qu'à la conservation des données de piste complètes.
@staticx, non, vous ne pouvez pas créer une piste 1 valide qui passera l'autorisation à moins d'avoir le CVV correct. La banque le rejettera. Le PAN est moins risqué à conserver que le CVV.
@JohnDeter: J'ai créé mes propres cartes. Ce n'est pas si dur. Tout ce dont vous avez besoin est une piste. C'est facile à générer. J'avais l'habitude de les créer tout le temps pour les tester. Et ils passeraient l'autorité
@JohnDeters: Les données discrétionnaires où le CVC1 est stocké sont entièrement facultatives. Vous pouvez y mettre des 0. CVC1 est là comme une sorte de somme de contrôle pour s'assurer que les données n'ont pas été falsifiées et qu'elles sont dans les données discrétionnaires. BEAUCOUP d'émetteurs ignorent ces données discrétionnaires car elles sont bien discrétionnaires. Le CVC2 qui se trouve généralement au dos de la carte est destiné uniquement aux yeux.
Andrew Hoffman
2014-07-17 23:13:34 UTC
view on stackexchange narkive permalink

Si vous voulez le faire, ajoutez une sorte d'obscurcissement. Je me suis juste assuré des votes négatifs, mais l'obscurcissement n'est pas sans valeur comme certains insisteront.

Si vous supposez que le système est connu, alors il n'y a aucune valeur. Mais si le système n'est pas connu, il y a une valeur absolue. Un IV utilisé pour «poivrer», comme Xander l'a dit, serait une forme d'obscurcissement, sans augmenter les collisions, et en maintenant la capacité d'interroger.

Un poivre ne serait cependant pas une obfuscation très efficace , sauf si le poivre est assez gros pour ne pas être deviné brutforce dans un laps de temps raisonnable. 100 octets aléatoires seraient peut-être exagérés, mais il n'y a aucune raison de ne pas aller trop loin.

Une autre chose qui pourrait être une dissimulation efficace serait de ne pas supposer que le poivre et le message sont atteints en même temps, donc que si vous répétez périodiquement les hachages dans un lot de nuit (en gardant une trace du nombre de tours), ils auraient besoin d'une autre information - combien de tours, ou comment les tours sont calculés.

Gardez à l'esprit que je ne pense pas que ce soit une bonne idée, je pense juste à haute voix ici. Si votre environnement est suffisamment sécurisé pour les cartes de crédit, non seulement je ne les hacherais pas, mais je les stockais dans une table conçue pour les performances de recherche les plus rapides.

Vérifiez la réponse acceptée .. il utilise un générateur de nombres aléatoires qui ne révèle rien sur le numéro de carte.
Oh, eh bien j'ai lu tout cela hier et il n'y avait pas de contexte ni de cas d'utilisation, ce qui change tout.
@FloatingRock: Votre point faible est le transit de la carte de l'application vers Braintree. En outre, il y a une faiblesse au niveau du lecteur de glissement vers le PC vers l'application. Il existe des solutions qui chiffrent de bout en bout, mais cela coûte de l'argent.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...