Matemáticamente, su n, e y d parecen respetar las reglas RSA (es decir, para cada primer r que divide n, r no divide n y d es un inverso de e módulo r-1). Sin embargo, RSA es un poco más que eso; también exige algunas reglas de relleno, que regulan cómo un mensaje (una secuencia de bytes) debe transformarse en un módulo entero n, y viceversa. El relleno estándar (consulte PKCS#1) implica que al menos 11 bytes se agregan al mensaje, y el resultado no debe seguir siendo n. Por lo tanto, con un módulo de 128 bits como el que muestra, la longitud máxima del mensaje de entrada para el cifrado será de 5 bytes.
Además, algunas implementaciones de RSA se negarán a trabajar con claves RSA que son demasiado pequeñas para la seguridad. Un módulo de 128 bits puede ser un factor en cuestión de segundos (ver this page para un applet Java de factorización, que usa ECM y tamiz cuadrático para factorizar números relativamente pequeños como el tuyo). El registro actual en factorización es de 768 bits; se recomienda una longitud de módulo de al menos 1024 bits para la seguridad a corto plazo. Una implementación típica de RSA aceptará usar claves de 512 bits, pero muchas rechazarán algo más corto que eso.
Otro posible problema es en el orden relativo de p y q. Las ecuaciones establecidas en PKCS # 1 asumen que p> q (de lo contrario, existe una resta adicional para realizar en la parte CRT). Si tiene p < q, entonces algunas implementaciones pueden equivocarse (lo encontré con la implementación estándar RSA de Microsoft en Windows). Simplemente compare p con q y cámbielos si es necesario.
Siempre a nivel práctico, algunas implementaciones generalizadas RSA rechazarán una clave RSA tal como el exponente público e no encaja dentro de un entero de 32 bits (esto incluye la implementación RSA usada en Windows, en particular a través de Internet Explorer para conectarse a los sitios web de HTTPS, así que cuando escribo "generalizado" lo digo en serio). La seguridad de RSA no parece verse afectada por la elección de e, por lo que es habitual elegir una pequeña e, que acelera la parte que utiliza la clave pública (es decir, cifrado, en lugar de descifrado o verificación de firma) , a diferencia de la generación de firmas). e = 3 es lo mejor que podría hacer, pero por razones tradicionales (incluido un malentendido histórico sobre una supuesta debilidad), a menudo se usa e = 65537. Solo necesita tener e relativamente mejor que p-1 y q-1. En una implementación práctica, primero elija e, luego realice un ciclo dentro de la generación para p y q, siempre que no coincidan con esa regla adicional.
Desde el punto de vista de la seguridad:
Su proceso de generación no es uniforme, en la que serán seleccionados algunos números enteros primos más frecuencia que otros. En particular, un primer p tal que p + 2 también es primo casi nunca será seleccionado. Con un tamaño de módulo adecuado, esto debería ser no ser un problema (ese tipo especial de sesgo se estudió y descubrió que no es un gran problema), pero no obstante es una mala relación pública.
Su n puede ser un poco más pequeño que el tamaño de destino, en caso de que ambos p y q están cerca del límite inferior de su rango de generación.Una manera simple de evitar que se va a restringir el rango de [sqrt (2) * 2 b-1, 2 b] tanto para p y q.
No puedo garantizar la seguridad del módulo random
que utiliza. Un generador de números aleatorios criptográficamente seguro no es una tarea fácil de hacer.
En términos generales, la implementación correcta de RSA sin filtrar información confidencial a través de varios canales secundarios (tiempo, uso de la memoria caché ...) no es una tarea fácil. Si desea seguridad en una configuración práctica, realmente debería realmente usar un paquete existente. Creo que Python tiene formas de interactuar con OpenSSL.
¿Qué pasa con 'M2Crypto.RSA.gen_key'? – jfs
Me parece bien, aunque un poco extraño. –
¿Esto solo es académico? Realmente no desea escribir su propia criptografía para código real. –