El crédito va a La respuesta de Jeff para los detalles y la respuesta de Steve que también fue útil. El crédito también va a La respuesta de Tylerl que incluía enlaces a Wikipedia para todas las funciones, particularmente modInverse
, también aclaró lo ambiguo. punto de partida para e
. Gracias, mejoré sus respuestas y, utilizando la información combinada de las tres respuestas, creé lo que espero sea una mejor respuesta.
La clave para hacer que la ingeniería inversa sea tan costosa es usar power-of . La raíz cuadrada no es tan dura, la potencia de 3 significa que necesitas una raíz en cubos, pero la potencia de 34,051,489 es bastante difícil. Hay otras operaciones matemáticas que son difíciles de aplicar ingeniería inversa. También hay varias formas de crear un algoritmo asimétrico, pero esta respuesta se centra en RSA. El más antiguo y el más común.
RSA Algorithm (basado en el Código Java )
Los cálculos a continuación deben realizarse con enteros de precisión arbitrarios . (Como BigInt o BigInteger)
Generando las claves:
- La longitud de la clave constante es
l
.
- Por lo general, la constante
e_start
puede =3
para simplificar. Sin embargo, 0x10001
es más común, en cualquier caso, un número primo es el mejor (por razones de rendimiento de generación de claves y probablemente otras razones).
-
p
y q
son los números primos positivos generados aleatoriamente, que requieren hasta l
bits para el almacenamiento. (Para mantener esto positivo, el primer bit siempre será 0
)
-
n
= p*q
Esto se usa tanto para el cifrado como para el descifrado.
-
e
comienza como e_start
. Esta será finalmente la parte de la clave de cifrado.
-
m
= (p-1)*(q-1)
se usa para convertir e
a d
, que se usará para el descifrado.
-
while(
gcd
(e,m)>1){e+=2}
Esto es necesario para que el siguiente paso funcione.
-
d=
modInverse
(e,m)
Esto realiza una operación aritmática estándar. Probablemente no valga la pena examinar mucho, especialmente si su lenguaje de programación tiene esto incorporado
Para cifrar o descifrar, primero convierta sus bytes en un único entero de precisión arbitraria.
Encriptación: encrypted=(plain^e)%n
Nota: si plain>=n
, debes dividir plain
en dos o más valores más pequeños y cifrarlos por separado.
Descifrado: plain=(encrypted^d)%n
El cifrado asimétrico suele ser menos eficiente que el cifrado simétrico. A veces, el cifrado asimétrico se utiliza solo para el intercambio de claves.