El método más sencillo para generar el módulo y la base de DH (denominados en conjunto los "parámetros de DH") es utilizar valores que ya se han generado. Esto no implica problemas de seguridad: varias personas pueden compartir los mismos parámetros de DH sin confiar entre sí.
Técnicamente, necesita tres valores: el módulo p , la base g y el orden de subgrupos q . Idealmente, q debería ser un número entero primo, y gq = 1 mod p .
Hay buenos valores previamente generados en RFC 3526 y RFC 5114 .
Si quieres crear el tuyo, entonces el algoritmo básico es "probar valores aleatorios hasta que alcances un número primo", pero hay detalles. Básicamente tienes dos opciones:
-
Genere valores q aleatorios y calcule p = 2 q +1; haz eso hasta que tanto q como p sean primos. Cuando haya encontrado un q y p con estas características, puede utilizar g = 4 como base; se garantiza que g tendrá orden exactamente q.
-
Genere valores q aleatorios del "tamaño correcto" para un orden de subgrupos (por ejemplo, 256 bits) hasta que encuentre un q principal. Luego genere los valores aleatorios r y calcule p = qr +1 para cada r ; haz eso hasta que encuentres un p p . En ese momento, genere un valor aleatorio h y calcule g = hr mod p . Ese valor g tendrá el orden q (es teóricamente posible pero en la práctica es muy improbable que obtenga g = 1; en ese caso, genere un nuevo al azar h).
El primer método permite el uso de un g muy pequeño, lo que proporciona una ligera ventaja de rendimiento al usar Diffie-Hellman (no es una gran ventaja en la práctica, algo como una velocidad de + 15% como máximo cuando se han aplicado optimizaciones adecuadas). Sin embargo, generar el módulo p con ese método es bastante costoso, ya que tiene que probar unos cuantos millones de valores de q hasta que encuentre uno de los que tanto p y q son primos.
Con el segundo método, la generación de parámetros es mucho más rápida, ya que se divide en dos etapas: primero encuentra un primer q (unos pocos cientos de intentos), luego un primer p (unos pocos miles de intentos). También le da un orden de subgrupo relativamente pequeño, lo que también puede ser bueno. Sin embargo, terminas con una base "enorme" g . Este método es realmente lo que se hace en DSS, como se especifica en FIPS 186-4 , así que si desea una especificación formal con todos los detalles establecidos, lea el apéndice A de esa norma ("Generación y validación de los parámetros del dominio FFC").
En cualquier caso, necesitará cálculos sobre grandes enteros, incluidas las exponenciales modulares y las pruebas de primalidad. Java proporciona ambos en java.math.BigInteger
.