En el espíritu del concurso Underhanded C , estoy comenzando un concurso de código Underhanded Code. El objetivo de este concurso es implementar directamente un código, mientras se oculta sutilmente un error nefasto en su interior.
El concurso
Eres un topo secreto ruso que trabaja en el departamento de TI de una agencia de espionaje estadounidense. Su jefe estadounidense acaba de pedirle que implemente un algoritmo de hash de contraseña para usar para cifrar mensajes secretos.
Su jefe quiere que implemente la siguiente función:
f: String -> byte[16]
que convierte una contraseña en una cantidad de 16 bytes adecuada para usar como clave AES. Su jefe quiere una función segura, lo que en este contexto significa que diferentes cadenas de contraseña deberían generar resultados diferentes con una probabilidad abrumadora. Por ejemplo, devolver el hash md5 de la entrada sería una implementación simple de f
.
Por supuesto, su verdadero jefe en la agencia de espionaje rusa querría que usted subvierta este proceso. Su tarea es implementar de f
manera que los rusos puedan descifrar todos los mensajes secretos cifrados con las claves devueltas por f
.
Para hacerlo, debe implementar de f
modo que devuelva solo un pequeño subconjunto de las 2 ^ 128 salidas posibles. En particular, f
debe devolver a lo sumo 2 ^ 16 resultados diferentes para que los rusos puedan hacer una búsqueda fácil por fuerza bruta de la clave correcta para cada mensaje cifrado que desean descifrar.
Tenga en cuenta, sin embargo, que el espionaje conlleva la pena de muerte. Para no quedar atrapado, su función f
debe generar al menos 2 ^ 8 resultados diferentes, por lo que una inspección superficial de algunas salidas f
es poco probable que revele un duplicado. Y lo más importante, el código que introduce para limitar el rango de f
debe parecer involuntario, no deliberado. Si alguna vez lo llevan a una sala del tribunal, debe haber alguna duda razonable sobre si introdujo el error deliberadamente o por accidente.
Juzgar
Yo y otros dos que recluto juzgaremos las entradas (envíeme un correo electrónico si desea juzgar). Estoy ofreciendo una recompensa de 200 reputación por la entrada ganadora. Las presentaciones deben cargarse antes del 1 de mayo.
La evaluación tendrá en cuenta los siguientes criterios:
- Se
f
adhiere a la especificación, es decir, genera entre 2 ^ 8 y 2 ^ 16 salidas posibles. No sienta que estos son límites duros, pero deduciremos puntos si está demasiado fuera de alcance. - ¿Es el error plausiblemente el resultado de un error involuntario?
- ¿Las salidas de
f
look al azar? - Cuanto más corta sea su implementación
f
, mejor. - Cuanto más clara sea su implementación
f
, mejor.
Notas
Puede usar cualquier idioma para implementar su código. Está tratando de ocultar un error a simple vista, por lo que no se sugiere el código ofuscado.
Es posible que desee echar un vistazo a algunos de los ganadores anteriores del concurso Underhanded C para tener una idea de lo que hace una buena presentación.
Las cadenas de entrada serán ascii imprimibles (32 a 126, inclusive). Puede asumir una longitud máxima razonable si lo desea.
fuente
Respuestas:
do
2 ^ 16 salidas posibles (o 2 ^ 8 veces el número de caracteres utilizados).
Utiliza la implementación MD5 de Linux, que es, AFAIK, bien. Pero esto da el mismo hash, por ejemplo, para "40" y "42".
EDITAR: renombrado
bcopy
amemcpy
(parámetros intercambiados, por supuesto).EDITAR: convertido de programa a función, para cumplir mejor los requisitos.
fuente
bcopy
paso ... es un buen desvío, ya que labcopy
función BSD real funcionaría correctamente aquí.bcopy
tiene errores. Lo cambiaré amemcpy
, y luego la misma implementación será válida.do
Puede que esta no sea la entrada más llamativa del concurso, pero creo que el siguiente es el tipo de función hash que podría haber hecho cualquier codificador demasiado inteligente para su propio bien, con una vaga idea del tipo de operaciones que ves en las funciones hash:
De hecho, la función hash no puede devolver más de L * 2048 resultados diferentes, donde L es el número de longitudes de cadena de entrada diferentes que pueden ocurrir. En la práctica, probé el código en 1.85 millones de líneas de entrada únicas de páginas manuales y documentos html en mi computadora portátil, y obtuve solo 85428 hashes únicos diferentes.
fuente
Scala:
Prueba, si el resultado no se ve similar para una entrada similar:
El error está usando solo primos para la codificación. En lugar de
valores, terminamos con
ya que hay 54 primos por debajo de 256.
fuente
5.22e27 >> 2^16
. No hay forma de fuerza bruta que muchas posibilidades.