Question

Je souhaite développer un système dans lequel je dois attribuer à chaque utilisateur un code PIN unique pour la sécurité. L'utilisateur entrera ce code PIN uniquement comme moyen de s'identifier. Ainsi, je ne veux pas que l'utilisateur soit capable de deviner un autre code d'utilisateur. En supposant que le nombre maximal d'utilisateurs que je vais avoir est 100000, combien de temps ce code PIN devrait-il être?

par exemple. 1234 4532 3423

Dois-je générer ce code via une sorte d'algorithme? Ou devrais-je le générer au hasard?

En gros, je ne veux pas que les gens sachent deviner le code PIN d’autres personnes, cela devrait supporter un nombre suffisant d’utilisateurs.

Je suis désolé si ma question me semble un peu déroutante, mais éclaircirait volontiers vos doutes.

merci beaucoup.

MISE À JOUR

Après avoir lu tous les articles ci-dessous, j'aimerais ajouter davantage de détails.

  1. Ce que je cherche à obtenir est très similaire à une carte à gratter.
  2. Un utilisateur reçoit une carte qu'il doit gratter pour trouver le code PIN.
  3. Maintenant, en utilisant ce code PIN, l'utilisateur doit pouvoir accéder à mon système.

Je ne peux pas ajouter de sécurité supplémentaire (nom d'utilisateur et mot de passe, par exemple), car cela dissuadera l'utilisateur d'utiliser la carte à gratter. Je veux rendre aussi difficile que possible de deviner le code secret dans les limites.

merci à vous tous pour vos réponses incroyables à nouveau.

Était-ce utile?

La solution

Si nous supposons 100 000 utilisateurs maximum, ils peuvent avoir des codes PIN uniques avec 0 à 99 999, par exemple. 5 chiffres.

Cependant, cela permettrait de deviner plus facilement les codes PIN avec le nombre maximum d'utilisateurs. Si vous pouvez limiter le nombre de tentatives sur le code PIN, vous pouvez avoir un code PIN plus court. par exemple. maximum de 10 tentatives infructueuses par IP et par jour.

Cela dépend également de la valeur de ce que vous protégez et de la gravité de la catastrophe si quelque chose se présentait.

Je choisirais 9 chiffres si vous voulez que le nom soit court ou 12 chiffres si vous voulez un peu plus de sécurité grâce aux tests automatiques.

Pour générer les codes confidentiels, je prendrais une version à haute résolution de l'époque, ainsi que des salt et peut-être un nombre pseudo-aléatoire, générez un hash et utilisez les 9 ou 12 premiers chiffres. Assurez-vous qu'il y a un délai raisonnable et aléatoire entre les nouvelles générations de codes PIN afin que ne les générez pas dans une boucle et, si possible, indiquez-les à l'initiative de l'utilisateur.

par exemple. Gauche (Sha1 (DateTime + Salt + PseudoRandom), 9)

Autres conseils

4 chiffres aléatoires devraient être suffisants si vous l'ajoutez à un ID utilisateur unique connu (qui pourrait toujours être un numéro) [comme recommandé par starblue]

Le générateur de nombres pseudo aléatoires devrait également convenir. Vous pouvez les stocker dans la base de données à l'aide d'un cryptage réversible (AES) ou d'un hachage à sens unique.

Votre principale préoccupation est de savoir combien de fois une personne peut entrer une broche de manière incorrecte avant d’être verrouillée. Cela devrait être faible, disons autour de trois ... Cela empêchera les gens de deviner les chiffres des autres peuples.

Si vous comptez plus de 6 chiffres et que les gens les oublient, ou pire, les écrivez sur un post-it sur leur moniteur.

En supposant qu'un compte se verrouille avec 3 tentatives incorrectes, puis avoir une NIP à 4 chiffres plus un composant ID utilisateur UserId (999999) + NIP (1234) vous donne une chance sur 3/0000 que quelqu'un devine. Est-ce acceptable? Si ce n’est pas le cas, prenez la longueur de la broche 5 et obtenez 3/100000

Puis-je suggérer une approche alternative? Consultez les mots de passe papier parfaits et le dérivés , vous êtes invité.

Vous pouvez utiliser ce " tel quel " pour générer des codes PIN uniques ou simplement pour générer un seul code PIN par utilisateur.

N'oubliez pas non plus que les codes PIN en double ne sont pas un problème en soi: toute attaque devrait alors simplement essayer plusieurs identifiants d'utilisateur.

(Avertissement relatif au kilométrage: je ne suis certainement pas un expert en sécurité.)

Voici une deuxième réponse: après la relecture, je suppose que vous ne voulez pas d'identifiant d'utilisateur en tant que tel - vous ne faites que valider un ensemble de cartes à gratter émises. Je suppose également que vous ne souhaitez pas utiliser de codes PIN alphabétiques.

Vous devez choisir une longueur de code PIN telle que la probabilité de deviner un code PIN valide soit inférieure à 1 / (nombre de tentatives contre lesquelles vous pouvez vous protéger). Ainsi, par exemple, si vous avez 1 million de codes PIN valides et que vous souhaitez vous protéger contre 10000 suppositions, vous aurez besoin d'un code PIN à 10 chiffres.

Si vous utilisez la version de John Graham-Cumming du système Perfect Paper Passwords , vous pouvez:

  1. Configurez ceci pour (par exemple) des décimales à 10 chiffres
  2. Choisissez une phrase secrète ou une phrase clé
  3. Générer (par exemple) le premier million de mots de passe (/ codes confidentiels)

Je soupçonne qu'il s'agit d'une procédure générique qui pourrait, par exemple, être utilisée pour générer également des identifiants de produit à 25 caractères alphanumériques.

Désolé de le faire par approximation successive; J'espère que cela vient un peu plus près de ce que vous recherchez.

Beaucoup de bonnes réponses jusqu'à présent: simples, efficaces et élégantes!

Je suppose que l'application ressemble à une loterie, chaque utilisateur recevant une carte à gratter et l'utilisant pour demander à votre application si & "il a déjà gagné! &"; Dans cette perspective, quelques nouvelles questions me viennent à l’esprit:

Composition du numéro de guerre ou son équivalent Internet: un utilisateur malhonnête peut-il frapper votre application à plusieurs reprises, par exemple en devinant tous les 10 chiffres à la suite? Si cela est possible, envisagez de limiter le nombre de tentatives depuis un emplacement particulier. Un moyen efficace pourrait simplement consister à refuser de répondre à plus d'une, disons, une tentative toutes les 5 secondes à partir de la même adresse IP. Cela rend les attaques automatisées inefficaces et évite le problème de verrouillage .

Problème de verrouillage : si vous verrouillez un compte définitivement après un certain nombre de tentatives infructueuses, vous êtes sujet à attaques par déni de service . L’attaquant ci-dessus pourrait verrouiller tous les utilisateurs , à moins que vous ne réactiviez les comptes après un certain temps. Mais cela n’est un problème que si vos codes confidentiels consistent en une concaténation évidente de l’ID utilisateur + clé, puisqu’un attaquant pourrait essayer chaque clé pour un ID utilisateur donné. Cette technique réduit également considérablement votre espace de clé, car seuls quelques chiffres du code PIN sont réellement aléatoires. D'autre part, si le code PIN est simplement une séquence de chiffres aléatoires, le verrouillage ne doit être appliqué qu'à l'adresse IP source. (Si une tentative échoue, aucun compte valide n'est affecté, donc que feriez-vous & "Verrouiller &";?)

Stockage des données : si vous créez réellement un système ressemblant à une loterie, il vous suffit de stocker les codes confidentiels gagnants ! Lorsqu'un utilisateur entre un code PIN, vous pouvez effectuer une recherche dans une liste relativement restreinte de codes PIN / prix (ou votre équivalent). Vous pouvez traiter & Quot; perdre & Quot; et des codes PIN non identiques, identiques à un & "; Désolé, meilleure chance la prochaine fois &"; message ou un " défaut " prix si l'économie a raison.

Bonne chance!

La question devrait être, & "Combien de suppositions sont nécessaires en moyenne pour trouver un code PIN valide, par rapport au nombre de suppositions que font les attaquants? &";

Si vous générez 100 000 codes à 5 chiffres, il faut évidemment 1 deviner. Il est peu probable que cela soit suffisant.

Si vous générez 100 000 codes à n chiffres, il faut (n-5) ^ 10 suppositions. Pour déterminer si cela suffit, vous devez examiner comment votre système répond à une mauvaise estimation.

Si un attaquant (ou tous les attaquants combinés) peut faire 1000 suppositions par seconde, alors n doit clairement être assez gros pour arrêter un attaquant déterminé. Si vous verrouillez définitivement leur adresse IP après 3 suppositions incorrectes, puisqu'un attaquant donné a peu de chances d'avoir accès à plus de 1 000 adresses IP, par exemple, n = 9 serait suffisant pour contrecarrer la quasi-totalité des attaquants. Évidemment, si vous devez faire face à des attaques distribuées ou à des attaques provenant d’un réseau de robots, 1 000 adresses IP par attaquant ne sont plus une hypothèse sûre.

Si, à l'avenir, vous devez émettre d'autres codes (plus de 100 000), il vous sera alors plus facile de deviner un code valide. Donc, il vaut probablement la peine de passer un peu de temps maintenant à vous assurer de vos besoins futurs en matière de dimensionnement avant de fixer une taille.

Compte tenu de votre cas d'utilisation de la carte à gratter, si les utilisateurs doivent utiliser le système pendant une longue période, je leur recommande de les autoriser (ou de les forcer) à & "mettre à niveau &"; leur code PIN à un nom d'utilisateur et un mot de passe de leur choix après la première utilisation du système. Ensuite, vous bénéficiez des avantages habituels nom d'utilisateur / mot de passe, sans oublier la facilité de première utilisation consistant à saisir simplement le numéro de la carte.

Pour ce qui est de savoir comment générer le nombre - probablement chacun de ceux que vous générez, vous les stockerez, auquel cas je dirais de les générer de manière aléatoire et d’éviter les doublons. Si vous les générez à l'aide de n'importe quel type d'algorithme et que quelqu'un le calcule, ils peuvent alors déterminer des codes PIN valides. Si vous sélectionnez un algorithme de sorte qu'il soit impossible à quelqu'un de le comprendre, alors quasiment est un générateur de nombres pseudo-aléatoires (l'autre propriété des PRNG étant qu'ils sont uniformément répartis, ce qui aide aussi ici car cela rend plus difficile de deviner les codes), auquel cas vous pouvez tout aussi bien les générer de manière aléatoire.

Si vous utilisez des algorithmes générateurs de nombres aléatoires, vous n'avez donc jamais de code PIN similaire à " 00038384882 " , commence par 0 (zéros), car les nombres entiers ne commencent jamais par & "; 0 &"; votre code PIN doit être démarré avec 1 à 9 chiffres sauf 0.

J'ai vu de nombreux codes PIN inclure et commencer de nombreux zéros, vous éliminez ainsi le premier million de numéros. Permutation nécessaire pour calculer le nombre de nombres éliminés.

Je pense que vous avez besoin de mettre 0 à 9 chiffres dans un hachage, de vous en séparer au hasard et de saisir le code PIN de votre chaîne.

Si vous souhaitez générer des codes PIN de type carte à gratter, vous devez utiliser des chiffres importants, d’une longueur d’environ 13 chiffres. De plus, ils doivent être similaires aux numéros de carte de crédit, avec une somme de contrôle ou un chiffre de vérification intégré au numéro lui-même. Vous devez avoir un algorithme pour générer une broche basée sur des données initiales, qui peuvent être une séquence de nombres. Le code PIN obtenu doit être unique pour chaque numéro de la séquence, de sorte que si vous générez 100 000 codes PIN, ils doivent tous être différents. De cette façon, vous pourrez valider un numéro non seulement en le comparant à une base de données, mais également en le vérifiant d’abord.

J'ai déjà écrit quelque chose à cette fin. Je ne peux pas vous donner le code, mais l’idée générale est la suivante:

  • Préparez un espace de 12 chiffres
  • Formatez le nombre en cinq chiffres (00000 à 99999) et répartissez-le sur l'espace d'une certaine manière. Par exemple, le nombre 12345 peut être réparti sous la forme __3_5_2_4__1. Vous pouvez modifier la manière dont vous étalez le nombre selon qu'il s'agisse d'un nombre pair ou impair, d'un multiple de 3, etc.
  • En fonction de la valeur de certains chiffres, générez plus de chiffres (par exemple, si le troisième chiffre est pair, créez un nombre impair et insérez-le dans le premier espace libre. Sinon, créez un nombre pair et insérez-le dans le deuxième. _83_5_2_4__1
  • Une fois que vous avez généré 6 chiffres, vous n’avez plus qu’un espace libre. Vous devez toujours laisser le même espace libre (par exemple, l'avant-dernier espace). Vous allez placer le chiffre de vérification à cet endroit.
  • Pour générer le chiffre de vérification, vous devez effectuer certaines opérations arithmétiques sur le nombre que vous avez généré, par exemple en ajoutant tous les chiffres des positions impaires et en les multipliant par un autre nombre, puis en soustrayant tous les chiffres des positions paires. enfin, en additionnant tous les chiffres (vous devez légèrement modifier l’algorithme en fonction de la valeur de certains chiffres). En fin de compte, vous avez un chiffre de vérification à inclure dans le code PIN généré.

Alors maintenant, vous pouvez valider vos codes PIN générés. Pour un code PIN donné, vous générez le chiffre de vérification et le comparez à celui inclus dans la broche. Si tout va bien, vous pouvez extraire le numéro d'origine en effectuant les opérations inverses.

Cela ne sonne pas très bien car cela ressemble à de la sécurité à travers l'obscurité, mais c'est la seule façon de l'utiliser. Il n'est pas impossible pour quelqu'un de deviner un code PIN, mais comme il s'agit d'un code à 12 chiffres avec un chiffre de vérification, ce sera très difficile, car vous devez essayer 1 000 000 000 000 de combinaisons et que vous ne disposez que de 100 000 codes PIN valables. sont 10 000 000 invalides.

Je dois mentionner que cela est utile pour les codes PIN jetables; une personne utilise l'un de ces codes une seule fois, par exemple pour charger un téléphone prépayé. Ce n’est pas une bonne idée d’utiliser ces broches comme jetons d’authentification, en particulier si c’est le seul moyen d’authentifier une personne (vous ne devez jamais JAMAIS authentifier une personne au moyen d’un seul élément de données; le minimum est un nom d’utilisateur + un mot de passe).

Il semble que vous souhaitiez utiliser le code PIN comme unique moyen d'identification des utilisateurs. Une solution viable consisterait à utiliser les cinq premiers chiffres pour identifier l'utilisateur, et ajoutez quatre chiffres en tant que code PIN.

Si vous ne souhaitez pas stocker les codes PIN, vous pouvez les calculer en appliquant un hachage cryptographiquement sécurisé (SHA1 ou supérieur). au numéro d'utilisateur plus un code secret à l'échelle du système.

  

Dois-je générer ce code via certains   sorte d'algorithme?

Non. Ce sera prévisible.

  

Ou devrais-je le générer de manière aléatoire?

Oui. Utilisez un générateur aléatoire cryptographique ou laissez l’utilisateur choisir son propre code PIN.

En théorie, 4 chiffres suffiront, car les émetteurs de cartes ATM parviennent à prendre en charge une très grande communauté (et ils ne peuvent évidemment pas être uniques ni nécessaires). Toutefois, dans ce cas, vous devez limiter le nombre de tentatives de saisie du code PIN et les verrouiller après autant de tentatives que le font les banques. Et vous devez également demander à l'utilisateur de fournir un ID utilisateur (dans le cas d'un guichet automatique, c'est effectivement sur la carte).

Si vous ne souhaitez pas les limiter de cette manière, il peut être préférable d’abandonner l’idée du code confidentiel et d’utiliser un mot de passe standard (qui correspond essentiellement à votre code confidentiel, avec seulement une très courte longueur et un jeu de caractères limité). . Si vous devez absolument le limiter aux chiffres (parce que vous avez un clavier NIP ou autre), envisagez de définir 4 longueurs minimales (configurables) plutôt que la longueur fixe.

Vous ne devriez pas stocker le code PIN en clair, où que ce soit (par exemple, le sel et le hachage comme un mot de passe). Toutefois, étant donné la longueur et le jeu de caractères limités, il sera toujours vulnérable à une recherche par force brute, à condition de le lui faciliter. pour le vérifier.

Si vous pouvez nous en dire plus sur vos besoins, vous pouvez également utiliser plusieurs autres systèmes (s'agit-il d'une application Web? système intégré? etc.).

Il existe une différence entre deviner le code PIN d'un utilisateur cible et celui d'un utilisateur valide . D'après votre cas d'utilisation, il semble que le code confidentiel soit utilisé pour accéder à certaines ressources. C'est à cette ressource que les attaquants pourraient s'adresser, pas à des identités particulières d'utilisateurs. Si tel est effectivement le cas, vous devez définir suffisamment de codes PIN valides sparse parmi tous les numéros possibles du même nombre.

Comme indiqué dans certaines réponses, vous devez rendre votre code confidentiel suffisamment aléatoire, que vous souhaitiez le générer à partir d'un algorithme. Le caractère aléatoire est généralement mesuré par l'entropie du code PIN.

Supposons maintenant que votre code PIN est d'entropie N et qu'il existe 2 ^ M utilisateurs dans votre système ( M < N ), la probabilité qu'une estimation aléatoire donne un code PIN valide est 2 ^ {MN} . (Désolé pour les notations en latex, j'espère que c'est assez intuitif). Ensuite, à partir de là, vous pouvez déterminer si cette probabilité est suffisamment faible avec N et M , ou calculer le N requis à partir de la probabilité souhaitée et M .

Il existe différentes façons de générer les codes confidentiels afin de ne pas avoir à mémoriser chaque code confidentiel que vous avez généré. Mais vous aurez besoin d'un très long code PIN pour le sécuriser. Ce n'est probablement pas ce que vous voulez.

Je l'ai déjà fait avec PHP et une base de données MySQL. J'avais une fonction de permutation qui garantissait d'abord que le nombre de codes requis - $ n, long # l, avec le nombre de caractères, $ c - pouvait être créé avant de commencer le processus de génération.

Ensuite, je stockais chaque nouveau code dans la base de données et le laissais me dire, via des erreurs UNIQUE KEY, qu’il y avait une collision (un double). Continuez ensuite jusqu'à ce que j'aie créé le nombre de codes créés avec succès. Vous pouviez bien sûr le faire en mémoire, mais je voulais conserver les codes pour les utiliser dans un publipostage MS Word. Alors ... alors je les ai exportés sous forme de fichier CSV.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top