Pregunta

Estoy buscando desarrollar un sistema en el que necesito asignar a cada usuario un código pin único por seguridad. El usuario solo ingresará este código pin como medio para identificarse. Por lo tanto, no quiero que el usuario pueda adivinar el código PIN de otro usuario. Suponiendo que el número máximo de usuarios que tendré es de 100000, ¿cuánto tiempo debe durar este código PIN?

p. 1234 4532 3423

¿Debo generar este código a través de algún tipo de algoritmo? ¿O debería generarlo al azar?

Básicamente, no quiero que las personas puedan adivinar el código PIN de otras personas y debería admitir un número suficiente de usuarios.

Lo siento si mi pregunta suena un poco confusa pero con gusto aclararía cualquier duda.

muchas gracias.

UPDATE

Después de leer todas las publicaciones a continuación, me gustaría agregar más detalles.

  1. Lo que estoy tratando de lograr es algo muy similar a una tarjeta de rascar.
  2. Un usuario recibe una tarjeta que debe rascar para encontrar el código PIN.
  3. Ahora, usando este código PIN, el usuario debe poder acceder a mi sistema.

No puedo agregar seguridad adicional (por ejemplo, nombre de usuario y contraseña), ya que esto disuadirá al usuario de usar la tarjeta de rascar. Quiero que sea lo más difícil posible adivinar el código PIN dentro de las limitaciones.

gracias a todos por sus increíbles respuestas de nuevo.

¿Fue útil?

Solución

Si suponemos un máximo de 100,000 usuarios, entonces pueden tener PIN únicos con 0-99,999, es decir. 5 dígitos.

Sin embargo, esto facilitaría adivinar los PIN con el número máximo de usuarios. Si puede restringir el número de intentos con el PIN, puede tener un PIN más corto. p.ej. máximo de 10 intentos fallidos por IP por día.

También depende del valor de lo que está protegiendo y de lo catastrófico que sería si el extraño saliera.

Iría por 9 dígitos si desea mantenerlo corto o 12 dígitos si desea un poco más de seguridad de las conjeturas automáticas.

Para generar los PIN, tomaría una versión de alta resolución del tiempo junto con algunas salt y tal vez un número pseudoaleatorio, genere un hash y usa los primeros 9 o 12 dígitos. Asegúrese de que haya una demora razonable y aleatoria entre las nuevas generaciones de PIN para que no las genere en un bucle y, si es posible, hágalas iniciadas por el usuario.

ej. Izquierda (Sha1 (DateTime + Salt + PseudoRandom), 9)

Otros consejos

4 dígitos aleatorios deberían ser suficientes si lo agrega a un ID de usuario único y conocido (aún podría ser un número) [según lo recomendado por starblue]

El generador de números pseudoaleatorios también debería estar bien. Puede almacenarlos en la base de datos mediante cifrado reversible (AES) o hashing unidireccional

La principal preocupación que tiene es cuántas veces una persona puede ingresar incorrectamente el pin antes de que se bloquee. Esto debería ser bajo, digamos alrededor de tres ... Esto evitará que las personas adivinen los números de otras personas.

Si tiene más de 6 dígitos, la gente los olvidará o, lo que es peor, los escribirá en una nota adhesiva en su monitor.

Suponiendo que una cuenta se bloquea con 3 intentos incorrectos, luego tener un pin de 4 dígitos más un componente de ID de usuario UserId (999999) + Pin (1234) le da una posibilidad de 3/10000 de que alguien adivine. ¿Es esto aceptable? Si no, haga la longitud del pin 5 y obtenga 3/100000

¿Puedo sugerir un enfoque alternativo? Eche un vistazo a Perfect Paper Passwords , y derivados que solicitó.

Podrías usar esto " como es " para generar PIN de un solo uso o simplemente para generar un PIN único por usuario.

Tenga en cuenta también que los PIN duplicados no son un problema en sí mismos: cualquier ataque simplemente tendría que intentar múltiples ID de usuario.

(Advertencia de kilometraje: definitivamente no soy un experto en seguridad).


Aquí hay una segunda respuesta: desde la relectura, supongo que no desea una identificación de usuario como tal, solo está validando un conjunto de tarjetas de rascar emitidas. También supongo que no desea utilizar PIN alfabéticos.

Debe elegir una longitud de PIN tal que la probabilidad de adivinar un PIN válido sea inferior a 1 / (El número de intentos contra los que puede protegerse). Entonces, por ejemplo, si tiene 1 millón de PIN válidos y desea protegerse contra 10000 conjeturas, necesitará un PIN de 10 dígitos.

Si usa la versión de John Graham-Cumming"> del sistema Perfect Paper Passwords , puede:

  1. Configure esto para (digamos) pines decimales de 10 dígitos
  2. Elija una frase secreta IV / clave
  3. Genere (digamos) el primer millón de contraseñas (/ PIN)

Sospecho que este es un procedimiento genérico que, por ejemplo, podría usarse para generar identificadores de productos alfanuméricos de 25 también.

Perdón por hacerlo por aproximación sucesiva; Espero que se acerque un poco más a lo que estás buscando.

Muchas respuestas geniales hasta ahora: ¡simple, efectivo y elegante!

Supongo que la aplicación es algo así como una lotería, ya que cada usuario recibe una tarjeta de rascar y la usa para preguntarle a su aplicación si & "; ¡ya ganó! &"; Entonces, desde esa perspectiva, me vienen a la mente algunos problemas nuevos:

Marcación de guerra , o su equivalente en Internet: ¿Puede un usuario deshonesto golpear su aplicación repetidamente, por ejemplo, adivinando cada número de 10 dígitos sucesivamente? Si esa es una posibilidad, considere limitar el número de intentos desde una ubicación en particular. Una forma efectiva podría ser simplemente negarse a responder más de, por ejemplo, un intento cada 5 segundos desde la misma dirección IP. Esto hace que los ataques controlados por máquinas sean ineficientes y evita el problema de bloqueo .

Problema de bloqueo : si bloquea una cuenta permanentemente después de cualquier número de intentos fallidos, es propenso a ataques de denegación de servicio . El atacante anterior podría bloquear efectivamente a cada usuario a menos que reactive las cuentas después de un período de tiempo. Pero esto es un problema solo si sus PIN consisten en una concatenación obvia de ID de usuario + clave, porque un atacante podría probar cada clave para una ID de usuario determinada. Esa técnica también reduce drásticamente su espacio clave porque solo unos pocos dígitos del PIN son verdaderamente aleatorios. Por otro lado, si el PIN es simplemente una secuencia de dígitos aleatorios, el bloqueo solo debe aplicarse a la dirección IP de origen. (Si falla un intento, no se ve afectada una cuenta válida, entonces ¿qué & Quot; bloquear & Quot ;?)

Almacenamiento de datos : si realmente está construyendo algún tipo de sistema de lotería, ¡ solo necesita almacenar los PIN ganadores ! Cuando un usuario ingresa un PIN, puede buscar una lista relativamente pequeña de PIN / premios (o su equivalente). Puede tratar & Quot; perder & Quot; y PIN inválidos idénticamente con un " Lo siento, ¡mejor suerte la próxima vez " mensaje o un " predeterminado " premio si la economía es correcta.

¡Buena suerte!

La pregunta debería ser, & "; ¿cuántas suposiciones son necesarias en promedio para encontrar un código PIN válido, en comparación con cuántas suposiciones están haciendo los atacantes? &";

Si genera 100 000 códigos de 5 dígitos, entonces obviamente se necesita 1 conjetura. Es poco probable que esto sea lo suficientemente bueno.

Si genera 100 000 códigos de n dígitos, se requieren (n-5) ^ 10 conjeturas. Para determinar si esto es lo suficientemente bueno, debe considerar cómo responde su sistema a una suposición errónea.

Si un atacante (o todos los atacantes combinados) pueden hacer 1000 conjeturas por segundo, entonces claramente n tiene que ser bastante grande para detener a un atacante determinado. Si bloquea permanentemente su dirección IP después de 3 conjeturas incorrectas, dado que es poco probable que un atacante determinado tenga acceso a más de, digamos, 1000 direcciones IP, n = 9 sería suficiente para frustrar a casi todos los atacantes. Obviamente, si se enfrenta a ataques distribuidos, o ataques desde una botnet, entonces 1000 direcciones IP por atacante ya no son una suposición segura.

Si en el futuro necesita emitir más códigos (más de 100 000), entonces obviamente facilitará adivinar un código válido. Por lo tanto, probablemente valga la pena pasar un tiempo ahora asegurándose de sus futuras necesidades de escalado antes de fijar un tamaño.

Dado su caso de uso de la tarjeta de rascar, si los usuarios van a utilizar el sistema durante mucho tiempo, recomendaría permitirles (u obligarlos) a " actualizar " su código PIN a un nombre de usuario y contraseña de su elección después del primer uso del sistema. Luego obtienes las ventajas habituales de nombre de usuario / contraseña, sin descartar la facilidad del primer uso de simplemente escribir el número de la tarjeta.

En cuanto a cómo generar el número, presumiblemente cada uno que generes guardarás, en cuyo caso diría que los generes al azar y descartes los duplicados. Si los genera utilizando cualquier tipo de algoritmo, y alguien descubre el algoritmo, entonces pueden descubrir códigos PIN válidos. Si selecciona un algoritmo de modo que no sea posible que alguien descubra el algoritmo, entonces casi es un generador de números pseudoaleatorio (la otra propiedad de los PRNG es que están distribuidos de manera uniforme, lo que ayuda aquí también porque hace que sea más difícil adivinar los códigos), en cuyo caso también podría generarlos al azar.

Si usa algoritmos generadores de números aleatorios, entonces nunca tiene un PIN como " 00038384882 " , comienza con 0 (ceros), porque los números enteros nunca comienzan con " 0 " ;. su PIN debe comenzar con 1-9 números excepto 0.

He visto que muchos números PIN incluyen y comienzan muchos ceros, por lo que elimina el primer millón de números. La permutación necesita cálculos para la cantidad de números eliminados.

Creo que necesita poner números 0-9 en un hash, y pasar aleatoriamente del hash, y hacer su número PIN de cadena.

Si desea generar códigos PIN de tipo tarjeta de rascar, debe usar números grandes, de aproximadamente 13 dígitos; y también, deben ser similares a los números de tarjeta de crédito, tener una suma de verificación o un dígito de verificación incrustado en el número mismo. Debe tener un algoritmo para generar un pin basado en algunos datos iniciales, que pueden ser una secuencia de números. El pin resultante debe ser único para cada número en la secuencia, de modo que si genera 100,000 códigos pin todos deben ser diferentes. De esta forma, podrá validar un número no solo al compararlo con una base de datos, sino que también puede verificarlo primero.

Una vez escribí algo para ese propósito, no puedo darle el código, pero la idea general es esta:

  • Prepare un espacio de 12 dígitos
  • Formatee el número como cinco dígitos (00000 a 99999) y extiéndalo a lo largo del espacio de cierta manera. Por ejemplo, el número 12345 puede extenderse como __3_5_2_4__1. Puede variar la forma en que distribuye el número dependiendo de si es un número par o impar, o un múltiplo de 3, etc.
  • Según el valor de ciertos dígitos, genere más dígitos (por ejemplo, si el tercer dígito es par, luego cree un número impar y colóquelo en el primer espacio abierto; de lo contrario, cree un número par y póngalo en el segundo abierto espacio, p. ej. _83_5_2_4__1
  • Una vez que haya generado 6 dígitos, solo tendrá un espacio abierto. Siempre debe dejar el mismo espacio abierto (por ejemplo, el penúltimo espacio). Colocará el dígito de verificación en ese lugar.
  • Para generar el dígito de verificación, debe realizar algunas operaciones aritméticas en el número que ha generado, por ejemplo, agregar todos los dígitos en las posiciones impares y multiplicarlos por algún otro número, luego restar todos los dígitos en las posiciones pares, y finalmente sumando todos los dígitos (debe variar un poco el algoritmo en función del valor de ciertos dígitos). Al final tiene un dígito de verificación que incluye en el código PIN generado.

Entonces ahora puede validar sus códigos PIN generados. Para un código pin dado, genera el dígito de verificación y lo compara con el incluido en el pin. Si está bien, puede extraer el número original realizando las operaciones inversas.

No suena tan bien porque parece seguridad a través de la oscuridad, pero es la única forma en que puedes usar esto. No es imposible que alguien adivine un código PIN, pero al ser un código de 12 dígitos con un dígito de verificación, será muy difícil ya que tiene que probar 1,000,000,000,000 de combinaciones y solo tiene 100,000 códigos PIN válidos, por lo que para cada código PIN válido allí son 10,000,000 inválidos.

Debo mencionar que esto es útil para códigos pin desechables; una persona usa uno de estos códigos solo una vez, por ejemplo para cargar un teléfono prepago. No es una buena idea usar estos pines como tokens de autenticación, especialmente si es la única forma de autenticar a alguien (nunca debe autenticar a alguien solo a través de un solo dato; el mínimo es nombre de usuario + contraseña)

Parece que desea utilizar el código PIN como único medio de identificación para los usuarios. Una solución viable sería utilizar los primeros cinco dígitos para identificar al usuario, y agregue cuatro dígitos como código PIN.

Si no desea almacenar PIN, se pueden calcular aplicando un hash criptográficamente seguro (SHA1 o mejor) al número de usuario más un código secreto de todo el sistema.

  

¿Debo generar este código a través de alguna   tipo de algoritmo?

No. Será predecible.

  

¿O debería generarlo al azar?

Sí Utilice un generador aleatorio criptográfico o deje que el usuario elija su propio PIN.

En teoría, 4 dígitos serán suficientes, ya que los emisores de tarjetas de cajero automático logran apoyar a una comunidad muy grande con solo eso (y obviamente, no pueden ser y no necesitan ser únicos). Sin embargo, en ese caso, debe limitar el número de intentos de ingresar el PIN y bloquearlos después de tantos intentos como lo hacen los bancos. Y también debe hacer que el usuario proporcione una identificación de usuario (en el caso de cajero automático, que está efectivamente en la tarjeta).

Si no desea limitarlos de esa manera, puede ser mejor deshacerse de la idea del PIN y usar una contraseña estándar (que es esencialmente su PIN, solo con una longitud muy corta y un conjunto de caracteres limitado) . Si absolutamente debe restringirlo a números (porque tiene un PIN pad o algo así), entonces considere hacer 4 una longitud mínima (configurable) en lugar de la longitud fija.

No debe almacenar el PIN en ningún lugar (p. ej., sal y hash como una contraseña), sin embargo, dada la corta longitud y el conjunto de caracteres limitado, siempre será vulnerable a una búsqueda de fuerza bruta, dada una manera fácil para verificarlo.

Hay varios otros esquemas que también se pueden usar, si puede contarnos más acerca de sus requisitos (¿se trata de una aplicación web? ¿sistema incorporado? etc.).

Hay una diferencia entre adivinar el PIN de un usuario objetivo y el de cualquier usuario válido. Según su caso de uso, parece que el PIN se usa para obtener acceso a cierto recurso, y es ese recurso el que los atacantes pueden estar buscando, no identidades particulares de los usuarios. Si ese es el caso, deberá hacer que los números PIN válidos sean lo suficientemente dispersos entre todos los números posibles de los mismos dígitos.

Como se menciona en algunas respuestas, debe hacer que su PIN sea lo suficientemente aleatorio, independientemente de si desea generarlo a partir de un algoritmo. La aleatoriedad generalmente se mide por la entropía del PIN.

Ahora, supongamos que su PIN es de entropía N , y hay 2 ^ M usuarios en su sistema ( M < N ), la probabilidad de que una suposición aleatoria arroje un PIN válido es 2 ^ {MN} . (Perdón por las anotaciones de látex, espero que sea lo suficientemente intuitivo). Luego, a partir de ahí, puede determinar si esa probabilidad es lo suficientemente baja dados N y M , o calcular la N requerida a partir de la probabilidad deseada y M .

Hay varias formas de generar los PIN para que no tenga que recordar cada PIN que generó. Pero necesitará un PIN muy largo para que sea seguro. Esto probablemente no sea lo que quieres.

He hecho esto antes con PHP y una base de datos MySQL. Tenía una función de permutaciones que primero aseguraría que la cantidad de códigos requeridos - $ n, con una longitud de $ l, con la cantidad de caracteres, $ c - pudiera crearse antes de comenzar el proceso de generación.

Luego, almacenaba cada código nuevo en la base de datos y dejaba que me dijera a través de errores de CLAVE ÚNICA, que hubo una colisión (duplicado). Luego continúe hasta que haya ganado $ n número de códigos creados con éxito. Por supuesto, podría hacer esto en la memoria, pero quería mantener los códigos para usar en una combinación de correspondencia de MS Word. Entonces ... luego los exporté como un archivo CSV.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top