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:
- derivar clave de PIN: K = PBKDF2 (pw = PIN, count = 1, output = 128)
- codifique la clave secreta DH: SKE = I2OSP (SK, len (n))
- cifrar con clave derivada: C = AES_CTR (K, 0, SKE)
Descifrado:
- derivar clave de PIN: K = PBKDF2 (pw = PIN, count = 1, output = 128)
- descifrar con clave derivada: SKE = AES_CTR (K, 0, C)
- 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.