1. Generación de la clave pública y privada:

  • (1) Elige aleatoriamente dos números primos grandes p y q, y construye n = p*q;
  • (2) Calcula la función de Euler φ(n) = (p-1) * (q-1);
  • (3) Elige aleatoriamente e, de modo que gcd(e, φ(n)) = 1, es decir, e y φ(n) son primos entre sí; gcd se refiere a calcular el máximo común divisor;
  • (4) Calcula d, de modo que e*d ≡ 1 (mod φ(n)), es decir, d es el inverso multiplicativo de e.

2. Proceso de cifrado:

  • (1) La información a cifrar (texto plano) es m, m < n; (porque se necesita realizar la operación de módulo, si m es mayor que n, las operaciones posteriores no se cumplirán; por lo tanto, cuando la información es más grande que n, se debe cifrar por bloques);

  • (2) El texto cifrado c se genera como $$ c = m^e mod (n) $$

3. Descifrado

$$ c^d mod (n) = (m^e)^d mod (n) = m^(d*e) mod (n) ; $$

3. Descifrado

$$ c^d mod (n) = (m^e)^d mod (n) = m^(d*e) mod (n) ; $$

¿Por qué se puede descifrar?

Se necesita usar el teorema de Euler (en realidad es una generalización del pequeño teorema de Fermat).

a^φ(n) ≡ 1 (mod n),

Generalizando más: a^(φ(n)k) ≡ 1 (mod n),

Obtenemos a^(φ(n)k+1) ≡ a (mod n)

Observa que ed ≡ 1 mod φ(N), es decir: ed = 1 + k*φ(N).

Por lo tanto, $$ M^(de) mod N = M^1 + kφ(N) mod N = M $$

4. El código es el siguiente

Ejemplo

#coding=utf-8 #__author__ = 'ralph' import random def extendedGCD(a, b): #a*xi + b*yi = ri if b == 0: return (1, 0, a) #a*x1 + b*y1 = a x1 = 1 y1 = 0 #a*x2 + b*y2 = b x2 = 0 y2 = 1 while b != 0: q = a / b #ri = r(i-2) % r(i-1) r = a % b a = b b = r #xi = x(i-2) - q*x(i-1) x = x1 - q*x2 x1 = x2 x2 = x #yi = y(i-2) - q*y(i-1) y = y1 - q*y2 y1 = y2 y2 = y return(x1, y1, a) def computeD(fn, e): (x, y, r) = extendedGCD(fn, e) #y maybe < 0, so convert it if y < 0: return fn + y return y def keyGeneration(p,q,e): #generate public key and private key n = p * q fn = (p-1) * (q-1) d = computeD(fn, e) return (d,n) p_v = int(raw_input('Ingrese el valor de p (decimal)\n')) q_v = int(raw_input('Ingrese el valor de q (decimal)\n')) e_v = int(raw_input('Ingrese el valor de e (decimal)\n')) c_v = int(raw_input('Ingrese el valor del texto cifrado c (decimal)\n')) (d,n) = keyGeneration(p_v,q_v,e_v) # Generar d y n m = pow(c_v,d,n) print ("El texto plano m obtenido es:"+str(m))

Cuando se ingresan los valores p: 18443, q: 49891, e: 19,

Valor del texto cifrado c:

70479679275221115227470416418414022368270835483295235263072905459788476483295235459788476663551792475206804459788476428313374475206804459788476425392137704796792458265677341524652483295235534149509425392137428313374425392137341524652458265677263072905483295235828509797341524652425392137475206804428313374483295235475206804459788476306220148

El resultado obtenido se mostrará

El texto plano m obtenido es: 88455713