java - net - Generación del par de llaves RSA Bouncy Castle usando API ligera
librería bouncycastle (4)
Sorprendentemente, hay muy poca información en la Web sobre el uso de la API ligera de Bouncy Castle. Después de mirar un rato, pude armar un ejemplo básico:
RSAKeyPairGenerator generator = new RSAKeyPairGenerator();
generator.init(new RSAKeyGenerationParameters
(
new BigInteger("10001", 16),//publicExponent
SecureRandom.getInstance("SHA1PRNG"),//prng
1024,//strength
80//certainty
));
AsymmetricCipherKeyPair keyPair = generator.generateKeyPair();
Tengo una comprensión básica de RSA y las matemáticas que ocurren detrás de las escenas, así que entiendo qué son publicExponent
y strength
. Supongo que publicExponent
refiere a un coprime de phi(pq)
y de lo que deduzco que puede ser pequeño (como 3) siempre que se use el relleno adecuado. Sin embargo, no tengo idea de a qué se refiere la certainty
(en algún lugar se menciona que podría referirse a un porcentaje, pero quiero estar seguro). El uso de SecureRandom
es autoexplicativo. La documentación de RSAKeyGenerationParameters es completamente inútil (no sorprende). Mi única conjetura es que tiene algo que ver con la precisión de las claves generadas, pero una vez más quiero estar seguro. Entonces mi pregunta es ¿cuáles son los valores apropiados para la certainty
y publicExponent
?
PD Por favor, no responda con "depende del contexto: qué tan segura quiere que sea la información". Es bastante seguro asumir el más alto nivel de seguridad (es decir, clave RSA de 4096 bits o superior) a menos que se especifique lo contrario ... También agradecería enlaces a fuentes que den buen ejemplo del uso de la API Lightweight de Bouncy Castle (no estoy en todos interesados en la implementación de JCA o cualquier ejemplo relacionado con ella).
Está utilizando valores correctos para ambos.
El publicExponent debe ser un número de Fermat . 0x10001 (F4) es el valor recomendado actual. 3 (F1) también es seguro.
La generación de claves RSA requiere números primos. Sin embargo, es imposible generar números primos absolutos. Como cualquier otra biblioteca de cifrado, BC usa números primos probables. La certeza indica qué tan seguro quieres que el número sea primo. Cualquier cosa superior a 80 ralentizará considerablemente la generación de claves.
Tenga en cuenta que el algoritmo RSA todavía funciona en el improbable caso de que el número primo no sea verdadero primo porque BC verifica la precocidad relativa.
Tendría que profundizar en su código fuente para ser "cierto", pero creo que el parámetro de certainty
se pasa directamente al constructor BigInteger
, que dice: "La probabilidad de que el nuevo BigInteger
represente un número primo excederá (1 - 1/2 de certeza ). El tiempo de ejecución de este constructor es proporcional al valor de este parámetro. "
Entonces, con un valor de 80, hay menos de 1 posibilidad en 2 80 de que el número no sea primo. El comentario sugiere que el tiempo de generación de números primos es lineal con respecto a este parámetro, pero debe probarlo para asegurarse de que elija aumentarlo. Puede tener sentido utilizar un valor que sea coherente con el tamaño de la clave que está utilizando. Por ejemplo, NIST dice que una clave RSA de 1024 bits es tan fuerte como una clave simétrica de 80 bits. Para una clave RSA de 2048 bits, es posible que desee utilizar una certeza de 112 bits (el tamaño de clave simétrica de fuerza equivalente), y así sucesivamente.
Parece que eres consciente de la vulnerabilidad de usar 3 como el exponente público en casos especiales. El valor 65537 se usa casi universalmente ahora.
Una buena referencia es FIPS PUB 186-3 . En particular, la sección 3 del apéndice B tiene muchos parámetros de seguridad, así como algoritmos de generación principal. certainty
es el número de iteraciones de la prueba de primalidad Miller-Rabin.
Consulte esta respuesta en crypto.stackexchange.com para obtener más información sobre cómo debe calcularse su valor de certeza.
Vista previa de la respuesta de Paŭlo Ebermann:
La certeza de x bits significa que la probabilidad de que algo (en este caso p sea primo) no sea verdadero es menor que 2-x. Esta es la misma probabilidad que adivinar correctamente un valor aleatorio de x bits en el primer intento, de ahí el nombre.
¿Cómo seleccionar x? Queremos que la probabilidad de que p (yq) no sea primo sea lo suficientemente pequeña como para que una probabilidad de falla en este punto no sea mayor que otras formas en que el sistema podría romperse, como adivinar una clave simétrica, factorizar el módulo, etc.
Entonces aquí una tabla de correspondencia de tamaños de clave simétricos y asimétricos debería ayudar. http://www.keylength.com/ Elija la misma certeza primordial que elegiría un tamaño de clave simétrica que acompaña el uso de su clave pública.