Cifre el secreto con un PIN numérico, pero permita intentos incorrectos

3

Estoy buscando un método para cifrar un secreto con un PIN numérico de manera que si un atacante intenta descifrar con el PIN incorrecto, la salida debería ser diferente.

Por ejemplo, si el secreto es ABCDE y el PIN es 5533, y el atacante intenta descifrarlo con el PIN incorrecto 1234, la salida debe ser BASDAFF (una cadena aleatoria que se parece al secreto).

Quiero usar este método para codificar la clave privada de Diffie Hellman con PIN, para que se genere un secreto incluso si el PIN es incorrecto.

    
pregunta DAKZH 24.04.2018 - 09:07
fuente

3 respuestas

3

El cifrado con un PIN generalmente no es seguro ya que el PIN en sí mismo no es lo suficientemente aleatorio: un atacante puede simplemente forzar el cifrado. Sin embargo, supongo que usted se detendría (después de X veces) una vez que el procedimiento Diffie-Hellman no resultara en el secreto compartido correcto.

Necesitará un PBKDF (función de derivación de clave basada en contraseña) para crear una clave simétrica a partir de un número PIN. Para hacer esto, puede dejar el número de iteración o el factor de trabajo a un número bajo. La cantidad de PIN será demasiado pequeña para protegerla contra la fuerza bruta de todos modos.

Sin embargo, hay un problema aquí: el secreto de Diffie-Hellman es aleatorio, pero es aleatorio dentro de un rango de orden n. Eso significa que si solo utiliza el cifrado binario que ejecuta en un problema: el valor devuelto puede ser demasiado alto y no encajar en el rango, lo que indica inmediatamente a un atacante que el resultado no es válido. El orden n es parte de los parámetros del dominio y, por lo tanto, se conoce públicamente.

En general, sin embargo, el orden n se elige para ser muy alto, generalmente comenzando con al menos 8 bytes establecidos en FFh. Compruebe, por ejemplo, los parámetros aquí . Si está utilizando uno de estos parámetros de dominio, simplemente puede usar el modo de contador (CTR) para cifrar su clave secreta DH. Si no reutiliza el PIN para el cifrado (incluso en el tiempo), entonces podría usar un cero byte IV, de modo que el tamaño del texto cifrado no sea mayor que el tamaño del número secreto de texto simple. El modo de contador siempre se descifra, no hay manera de distinguir entre el secreto correcto de la clave privada DH y uno incorrecto.

Sin embargo, debe asegurarse de codificar su clave privada en el mismo número de bytes que el pedido , o se identificarán fácilmente los números más pequeños para la clave privada.

Por lo tanto, es posible que necesites:

Encriptación:

  1. derivar clave de PIN: K = PBKDF2 (pw = PIN, count = 1, output = 128)
  2. codifique la clave secreta DH: SKE = I2OSP (SK, len (n))
  3. cifrar con clave derivada: C = AES_CTR (K, 0, SKE)

Descifrado:

  1. derivar clave de PIN: K = PBKDF2 (pw = PIN, count = 1, output = 128)
  2. descifrar con clave derivada: SKE = AES_CTR (K, 0, C)
  3. descifre la clave secreta DH: SK = OS2IP (SKE)

PBKDF2 es parte de la especificación PKCS # 5 para el cifrado basado en contraseña (PBE). Es relativamente común en las bibliotecas criptográficas, I2OSP y OS2IP se explican aquí .

Hay formas de realizar su tarea, incluso si el orden n es cualquier número grande. En general, lo que está buscando es Format Preserving Encryption. Con la mayoría de los FPE, no solo obtiene el texto cifrado en el mismo rango que el texto sin formato, sino que también obtendría el texto sin cifrar en el rango, incluso si la clave es incorrecta. Tenga en cuenta que la construcción de FPE debe ser tal que el atacante no pueda distinguir la corrección dentro del propio algoritmo de descifrado.

Afortunadamente, mi amigo fgrieu publicó una buena solución para esto en el sitio de criptografía .

Pido disculpas si esto es demasiado para asimilar, pero la complejidad es aún mejor que la inseguridad. Utilice mejor uno de los parámetros con un orden grande n para que no tenga que implementar la respuesta dada por fgrieu.

    
respondido por el Maarten Bodewes 24.04.2018 - 12:40
fuente
3

Técnicamente, así es como funciona el cifrado no autenticado de forma predeterminada: una clave incorrecta producirá un texto sin formato incorrecto. Solo si hay autenticación o verificación de errores (y en las bibliotecas listas para usar, generalmente existe) el descifrado producirá un error.

Tenga en cuenta que es trivial forzar el PIN por fuerza bruta debido a su pequeño espacio de teclas, a menos que la cantidad de ataques sea muy limitada y no puedan distribuirse entre muchas máquinas. El PIN se puede hacer perecedero para ese fin, eliminando el archivo después de N intentos, siempre que haya una forma más permanente de autenticación.

En general, NO debe cifrar el secreto con el PIN en sí, sino con una clave generada usando un PBKDF (bcrypt, scrypt, argon2) de secretos conocidos por el usuario, como la contraseña o el PIN y un salt. Depende de lo que intentas hacer exactamente.

    
respondido por el Therac 24.04.2018 - 10:12
fuente
-3

No me gusta esto, pero si está seguro de que el cliente sabrá el secreto y sabrá que ingresaron en el pin incorrecto, basó los resultados bien. Esto irá principalmente donde se da el mensaje de error.

Puede generar un texto aleatorio mediante el uso de

tr -dc A-Za-z0-9 </dev/urandom | head -c 1024 > random.txt

Esto está en Linux.

Dependiendo de tu idioma puedes modificar.

Editar: olvidé agregar que can puede dar lugar a un bajo rendimiento en una red, ya que se requiere que crees un texto aleatorio por cada intento fallido, por lo que la fuerza bruta puede dar lugar a un tiempo de CPU innecesario.

    
respondido por el S S 24.04.2018 - 09:37
fuente

Lea otras preguntas en las etiquetas