Implemente un programa de cifrado CipherSaber , como se describe a continuación. Pautas:
- La entrada más pequeña, en bytes, gana.
- Sin embargo, en una desviación de las normas de código de golf , puede publicar entradas interesantes, incluso si no son entradas serias de golf.
- Una entrada normalmente sería un programa que toma el texto sin formato de la entrada estándar y escribe el texto cifrado en la salida estándar, con la clave especificada (por el usuario) de la manera que prefiera.
- Sin embargo, si desea implementar esto como un procedimiento, también está bien.
- El IV debe provenir de un generador de números pseudoaleatorios criptográficamente seguro. Si su idioma no es compatible con eso, elija uno diferente. ;-)
- No utilice ninguna biblioteca específica de cifrado, llamadas al sistema o instrucciones (que no sean PRNG, como se estipula anteriormente). Por supuesto, las operaciones bit a nivel genéricas de bajo nivel están bien.
CipherSaber es una variante de RC4 / Arcfour, por lo que comenzaré describiendo esta última y luego los cambios que CipherSaber realiza.
0. RC4 / Arcfour
Arcfour está completamente especificado en otra parte , pero para completarlo, lo describiré aquí. (En caso de discrepancias entre el borrador de Internet y esta descripción, la primera es normativa).
Configuración clave
Configure dos matrices S
y S2
, ambas de longitud 256, donde k_1
es el primer byte de la clave y k_n
es el último.
S = [0, ..., 255]
S2 = [k_1, ..., k_n, k_1, ...]
( S2
se llena con los bytes de la clave, una y otra vez, hasta que se llenen los 256 bytes).
Luego, inicialice j
a 0 y baraje 256 veces:
j = 0
for i in (0 .. 255)
j = (j + S[i] + S2[i]) mod 256
swap S[i], S[j]
end
Esto completa la configuración clave. La S2
matriz ya no se usa aquí, y se puede eliminar.
Generación de flujo de cifrado
Inicialice i
ya j
0, luego genere la secuencia de claves de la siguiente manera:
i = 0
j = 0
while true
i = (i + 1) mod 256
j = (j + S[i]) mod 256
swap S[i], S[j]
k = (S[i] + S[j]) mod 256
yield S[k]
end
Cifrar / descifrar datos
- Para cifrar, XOR la salida del flujo de claves con el texto sin formato
- Para descifrar, XOR la salida del flujo de claves con el texto cifrado
1. CipherSaber
CipherSaber (que es lo que estamos implementando en esta pregunta) es una variación de RC4 / Arcfour de dos maneras:
10 bytes IV / nonce
Al cifrar un mensaje, se deben obtener 10 bytes aleatorios, como vía /dev/urandom
, y se deben escribir en los primeros 10 bytes de la salida cifrada. Al descifrar un mensaje, los primeros 10 bytes de la entrada son el IV utilizado para cifrarlo.
La etapa de configuración de la clave RC4 / Arcfour se ejecuta con passphrase || IV
la clave, donde passphrase
está la frase de contraseña especificada por el usuario, IV
es como se describió anteriormente y ||
es la concatenación. Entonces, una frase de contraseña de "¡Hola, mundo!" y una IV de "supercalif" (por improbable que sea :-P) resultaría en una clave de "¡Hola, supercalif!".
Múltiples iteraciones de configuración clave
Para ayudar a prevenir la vulnerabilidad que hizo que el cifrado WEP se rompiera por completo, el ciclo de barajado de la etapa de configuración de clave de RC4 se ejecuta un número de veces especificado por el usuario. El valor de j
debe conservarse entre iteraciones.
2. Vectores de prueba
Aquí hay algunos vectores de prueba que puede usar para probar sus programas. Además, ossifrage aprensivo creó una herramienta de cifrado y descifrado CipherSaber que puede usar para validar sus resultados.
Solo necesita implementar el programa de cifrado. No es necesario que suministre el programa de descifrado, pero la salida de su programa de cifrado debe ir correctamente a la entrada original cuando se procesa con un programa de descifrado implementado correctamente utilizando la clave correcta.
fuente
urandom
(que puede ser una entrada separada si lo desea) si le importa "ganar". :-)Python 2 -
373350326317 bytesPyth posiblemente vendrá más tarde. Define una función,
c(p,d,r,m)
que toma listas de bytes para frase de contraseña y datos, e int para repeticiones y modo que encripta cuando 1 y desencripta cuando 0. Esto se debe a que la única diferencia en ellos es tratar con el IV. Devuelve la lista de bytes.Aquí hay algunas funciones de código de prueba / ayudante:
fuente
else:v,d=d[:10],d[10:]
parte.Ruby - 263 caracteres
¡Esta es mi respuesta de Ruby a la pregunta original sobre stackoverflow en 2010! Es un codificador y decodificador todo en un programa.
Los parámetros son:
eod (
clave de codificación o decodificación)
número de veces
fuente
C, 312 bytes
Acepta un recuento de iteración de mezcla de clave y clave en la línea de comando, luego encripta todo en stdin a stdout. Utiliza la función de biblioteca BSD / Darwin
arc4random()
, que es un PRNG basado en RC4. Se siembra automáticamente, por lo que los resultados serán diferentes cada vez.Versión más ordenada:
Ejemplo:
fuente
Python - 266 caracteres
¡Esta es mi respuesta de Python a la pregunta original sobre stackoverflow en 2010! Es un codificador y decodificador todo en un programa.
Los parámetros son:
eod (
clave de codificación o decodificación)
número de veces
Esta versión intenta fusionar los 2 bucles del rc4 en uno (ahorra 11 bytes hasta ahora ...)
fuente