Dans l'esprit du concours Underhanded C , je lance un concours de code Underhanded. L’objectif de ce concours est d’implémenter directement du code, tout en y dissimulant de manière subtile un bogue infâme.
La compétition
Vous êtes une taupe russe secrète qui travaille au service informatique d'une agence d'espionnage américaine. Votre patron américain vient de vous demander de mettre en œuvre un algorithme de hachage de mot de passe à utiliser pour chiffrer les messages secrets.
Votre patron souhaite que vous implémentiez la fonction suivante:
f: String -> byte[16]
qui convertit un mot de passe en une quantité de 16 octets pouvant être utilisée comme clé AES. Votre patron souhaite une fonction sécurisée, ce qui signifie dans ce contexte que différentes chaînes de mots de passe doivent générer des résultats différents avec une probabilité écrasante. Par exemple, renvoyer le hachage md5 de l'entrée serait une simple implémentation de f
.
Bien sûr, votre vrai patron de l'agence d'espionnage russe voudrait que vous subvertissiez ce processus. Votre tâche consiste à mettre en place f
des systèmes permettant aux Russes de déchiffrer tous les messages secrets chiffrés à l'aide des clés renvoyées par f
.
Pour ce faire, vous devez implémenter f
afin de ne renvoyer qu'un petit sous-ensemble des 2 ^ 128 sorties possibles. En particulier, vous f
devez renvoyer au plus 2 ^ 16 résultats différents afin que les Russes puissent effectuer une recherche simple et brutale de la clé correcte pour chaque message chiffré qu'ils souhaitent déchiffrer.
Gardez toutefois à l'esprit que l'espionnage est passible de la peine de mort. Pour ne pas être pris au piège, votre fonction f
doit générer au moins 2 ^ 8 résultats différents, de sorte qu'une inspection superficielle de quelques sorties de f
ne donnera probablement pas un doublon. Et plus important encore, le code que vous introduisez pour limiter la portée f
doit paraître non intentionnel, et non délibéré. Si jamais vous êtes amené dans une salle d'audience, il doit exister un doute raisonnable quant à savoir si vous avez introduit le bogue délibérément ou par accident.
Juger
Les recrues et moi-même jugerons les entrées (envoyez-moi un courrier électronique si vous souhaitez juger). J'offre une prime de 200 points de réputation pour l'inscription gagnante. Les soumissions doivent être téléchargées avant le 1er mai.
Le jugement tiendra compte des critères suivants:
- Est -ce que
f
Adhérez à la spécification, à savoir qu'elle produit de entre 2 ^ 8 et 2 ^ 16 sorties possibles. Ne croyez pas que ce sont des limites strictes, mais nous déduirons des points si vous êtes trop loin des marges. - Le bogue est-il plausiblement le résultat d'une erreur involontaire?
- Les sorties de
f
look sont-elles aléatoires? - Plus votre mise en œuvre est courte
f
, mieux c'est. - Plus votre mise en œuvre sera claire
f
, mieux ce sera.
Remarques
Vous pouvez utiliser n'importe quel langage pour implémenter votre code. Vous essayez de cacher un bug à la vue de tous, donc le code obfusqué n'est pas suggéré.
Vous voudrez peut-être jeter un coup d'œil à certains des gagnants précédents du concours Underhanded C pour avoir une idée de ce qui fait une bonne soumission.
Les chaînes en entrée seront des caractères ASCII imprimables (32 à 126 inclus). Vous pouvez supposer une longueur maximale raisonnable si vous le souhaitez.
la source
Réponses:
C
2 ^ 16 sorties possibles (ou 2 ^ 8 fois le nombre de caractères utilisés).
Utilise l'implémentation MD5 de Linux, qui est, autant que je sache, bien. Mais cela donne le même hash, par exemple, pour "40" et "42".
EDIT: renommé
bcopy
enmemcpy
(paramètres échangés bien sûr).EDIT: Converti de programme en fonction, pour mieux répondre aux exigences.
la source
bcopy
étape ... c'est une belle erreur de direction, car labcopy
fonction BSD réelle fonctionnerait correctement ici.bcopy
buggy. Je vais le changer enmemcpy
, et ensuite la même implémentation deviendra valide.C
Ce n'est peut-être pas la participation la plus spectaculaire du concours, mais je pense que ce qui suit est le type de fonction de hachage qui aurait pu être effectué par un codeur trop intelligent, pour son propre bien, avec une vague idée du type d'opérations que vous voyez dans les fonctions de hachage:
En fait, la fonction de hachage ne peut pas renvoyer plus de L * 2048 résultats différents, L étant le nombre de longueurs de chaîne d'entrée différentes pouvant se produire. En pratique, j'ai testé le code sur 1,85 million de lignes de saisie uniques à partir de pages de manuel et de documents html sur mon ordinateur portable et je n'ai eu que 85428 hachages uniques différents.
la source
Scala:
Testez, si le résultat ne semble pas similaire pour une entrée similaire:
L'erreur utilise seulement des nombres premiers pour l'encodage. Au lieu de
valeurs, nous finissons avec
puisqu'il y a 54 nombres premiers en dessous de 256.
la source
5.22e27 >> 2^16
. Il n'y a aucun moyen de recourir à la force brutale avec autant de possibilités.