Es un algoritmo de cifrado simétrico (se utiliza la misma clave para cifrar y para descifrar) y de flujo ('Stream cipher'), es decir, opera habitualmente byte a byte sobre un texto en claro o mensaje a cifrar y una secuencia cifrante, pero puede operar sobre cualquier tamaño (bit a bit,...).
Aunque se utilizó de forma extendida en algunos de los protocolos más populares como TLS ('Transport Layer Security'), para proporcionar comunicaciones seguras por Internet, y WEP ('Wired Equivalent Privacy'), para añadir seguridad en las redes inalámbricas, actualmente se considera que es un algoritmo inseguro.
Básicamente, el algoritmo RC4 consiste en tres etapas:
1.- Inicialización del vector de estado (KSA, key-scheduling algorithm):
Convierte una clave (K) o semilla en una permutación inicial del vector de estado (S).
Al principio de esta etapa, el vector de estado (S) de 256 elementos se carga con todos los números secuenciales desde 0 a 255.
El emisor y receptor comparten una misma clave (K, cifrado simétrico). RC4 admite claves de 1 hasta 256 bytes de longitud, aunque típicamente se utilizan claves de longitud entre 5 y 16 bytes (40 - 128 bits).
En esta primera etapa del algoritmo RC4 se desordenan los 256 elementos del vector de estado (S) a partir de la clave secreta (K) compartida por emisor y receptor, iterándose por cada elemento de S de la siguiente manera (en el siguiente ejemplo K="CLAVE"):
1.1.- K="CLAVE"
1.2.- Desde i = 0 hasta 255
1.2.1.- Si = i
1.3.- j=0
1.4.- Desde i = 0 hasta 255
1.4.1.- j = (j + Si + ASCII_DEC(Ki mod longitud_clave(K))) mod 256
1.4.2.- Intercambiar_valores(Si, Sj)
Es decir:
- Para i = 0: j = 0 + 0 + 67 = 67; S0 = 67; S67 = 0
- Para i = 1: j = 67 +1 + 76 = 144; S1 = 144; S144 = 1
- Para i = 2: j = 144 + 2 + 65 = 211; S2 = 211; S211 = 2
- Para i = 3: j = 211 + 3 + 86 = 44; S3 = 44; S44 = 3
...
2.- Generación del flujo de cifrado (PRGA, pseudo-random generation algorithm):
Partiendo del vector de estado (S) obtenido en la etapa anterior se genera el flujo de cifrado o secuencia cifrante pseudoaleatoria KS.
En cada iteración del algoritmo se obtiene un byte del flujo de cifrado y se intercambian dos elementos del vector de estado (S). El flujo de cifrado tendrá la misma longitud que el mensaje a cifrar (M) o texto en claro (en el siguiente ejemplo M ="EJEMPLO CIFRADO"):
2.1.- M="EJEMPLO CIFRADO"; i = 0; j = 0
2.2.- Desde l = 0 hasta longitud_mensaje(M) - 1
2.2.1.- i = (i + 1) mod 256
2.2.2.- j = (j + Si) mod 256
2.2.3.- Intercambiar_valores(Si, Sj)
2.2.4.- KSl = S(Si+Sj) mod 256
Es decir:
- Para l = 0: i = 1; j = 144; S1 = 213; S144 = 144; KS0 = 212
- Para l = 1: i = 2; j = 164; S2 = 83; S164 = 20; KS1 = 236
- Para l = 2: i = 3; j = 76; S3 = 28; S76 = 168; KS2 = 164
- Para l = 3: i = 4; j = 193; S4 = 207; S193 = 117; KS3 = 169
...
3.- Cifrado:
XOR de cada byte del mensaje a cifrar con cada byte de la secuencia cifrante obtenida en el paso anterior:
3.1.- Desde i = 0 longitud_mensaje(M) - 1
3.1.1.- Ci = XOR(ASCII_DEC(Mi), KSi)
Creo un pequeño script en python:
# -*- coding: utf-8 -*-
# Implemención en python del algoritmo RC4
def KSA(K):
longitud_clave = len(K)
print('[+] Longitud de la clave ............', longitud_clave)
print('')
print('*** Inicialización del vector de estado (KSA, key-scheduling algorithm)')
print('[+] Carga del vector de estado (S) con los números secuenciales del 0 al 255')
for i in range(256):
S.append(i)
j=0
print('[+] Intercambio de elementos del vector de estado (S)')
for i in range(256):
j = (j + S[i] + ord(K[i % longitud_clave])) % 256
S[i],S[j] = S[j],S[i]
def PRGA(M):
longitud_mensaje = len(M)
print('[+] Longitud del mensaje a cifrar ...', longitud_mensaje)
print('')
print('*** Generación del flujo de cifrado (PRGA, pseudo-random generation algorithm)')
print('[+] Generación de la secuencia cifrante pseudoaleatoria KS')
i=j=0
for l in range(longitud_mensaje):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i],S[j] = S[j],S[i]
k = S[(S[i] + S[j])% 256]
KS.append(k)
def XOR(M):
longitud_mensaje = len(M)
print('')
print('*** Cifrado: XOR de cada byte mensaje a cifrar con cada byte secuencia cifrante)')
for i in range(longitud_mensaje):
C.append(ord(M[i])^KS[i])
S=[]
M = 'EJEMPLO CIFRADO'
K = 'CLAVE'
print('')
print('[+] Clave ...........................', K)
KSA(K)
# print(S)
KS=[]
print('')
print('[+] Mensaje a cifrar ................', M)
PRGA(M)
# print(KS)
C=[]
XOR(M)
print('[+] Criptograma ....................', C)
Y lo ejecuto:
Comentarios
Publicar un comentario