No espírito do Concurso C de Underhanded , estou iniciando um Concurso de Código de Underhanded. O objetivo deste concurso é implementar diretamente algum código, ocultando sutilmente um bug nefasto dentro dele.
O concurso
Você é uma toupeira secreta da Rússia que trabalha no departamento de TI de uma agência de espionagem americana. Seu chefe americano acabou de solicitar que você implemente um algoritmo de hash de senha para criptografar mensagens secretas.
Seu chefe deseja que você implemente a seguinte função:
f: String -> byte[16]
que converte uma senha em uma quantidade de 16 bytes adequada para uso como chave AES. Seu chefe deseja uma função segura, o que, nesse contexto, significa que diferentes cadeias de senha devem gerar resultados diferentes com uma probabilidade esmagadora. Por exemplo, retornar o hash md5 da entrada seria uma implementação simples de f
.
Obviamente, seu verdadeiro chefe na agência de espionagem russa gostaria que você subvertesse esse processo. Sua tarefa é implementar de f
forma que os russos possam descriptografar todas as mensagens secretas criptografadas usando as chaves retornadas por f
.
Para fazer isso, você deve implementar f
para que ele retorne apenas um pequeno subconjunto das 2 ^ 128 saídas possíveis. Em particular, você f
deve retornar no máximo 2 ^ 16 resultados diferentes, para que os russos possam fazer uma pesquisa fácil de força bruta pela chave correta para cada mensagem criptografada que desejam descriptografar.
Lembre-se, no entanto, que a espionagem acarreta a pena de morte. Para não ser pego, sua função f
deve gerar pelo menos 2 ^ 8 resultados diferentes, de modo que f
é improvável que uma inspeção superficial de algumas saídas revele uma duplicata. E o mais importante, o código que você introduz para limitar o intervalo f
deve parecer não intencional, não deliberado. Se você for levado a um tribunal, deve haver alguma dúvida razoável sobre se você introduziu o bug deliberadamente ou por acidente.
A julgar
Eu e mais duas pessoas recrutadas julgaremos as inscrições (envie-me um e-mail se desejar julgar). Estou oferecendo uma recompensa de 200 reputações pela entrada vencedora. As inscrições devem ser enviadas até 1º de maio.
O julgamento levará em consideração os seguintes critérios:
- Será que
f
aderem à especificação, ou seja, faz gerar entre 2 ^ 8 e 2 ^ 16 possíveis saídas. Não pense que esses são limites rígidos, mas deduziremos pontos se você estiver muito fora do alcance. - O erro é plausivelmente o resultado de um erro não intencional?
- As saídas
f
parecem aleatórias? - Quanto menor a sua implementação
f
, melhor. - Quanto mais clara sua implementação
f
, melhor.
Notas
Você pode usar qualquer idioma para implementar seu código. Você está tentando ocultar um bug à vista, portanto, código ofuscado não é sugerido.
Você pode dar uma olhada em alguns dos vencedores anteriores do concurso Underhanded C para ter uma ideia do que é uma boa finalização.
As seqüências de entrada serão ascii imprimíveis (32 a 126, inclusive). Você pode assumir um comprimento máximo razoável, se quiser.
fonte
Respostas:
C
2 ^ 16 saídas possíveis (ou 2 ^ 8 vezes o número de caracteres usados).
Usa a implementação MD5 do Linux, que é AFAIK, tudo bem. Mas isso fornece o mesmo hash, por exemplo, para "40" e "42".
EDIT: renomeado
bcopy
paramemcpy
(parâmetros trocados, é claro).EDIT: Convertido de programa em função, para melhor atender aos requisitos.
fonte
bcopy
etapa ... é uma boa direção errada, uma vez que abcopy
função BSD real funcionaria corretamente aqui.bcopy
é buggy. Vou mudar paramemcpy
e, em seguida, a mesma implementação se tornará válida.C
Essa pode não ser a entrada mais chamativa do concurso, mas acho que o seguinte é o tipo de função hash que poderia ter sido feita por qualquer codificador inteligente demais para o seu próprio bem, com uma vaga idéia do tipo de operações que você vê nas funções hash:
De fato, a função hash pode retornar não mais que L * 2048 resultados diferentes, onde L é o número de diferentes comprimentos de string de entrada que podem ocorrer. Na prática, testei o código em 1,85 milhão de linhas de entrada exclusivas de páginas de manual e documentos html no meu laptop, e obtive apenas 85428 hashes únicos diferentes.
fonte
Scala:
Teste, se o resultado não for semelhante para entradas semelhantes:
O erro está usando apenas primos para a codificação. Ao invés de
valores, terminamos com
pois há 54 números primos abaixo de 256.
fonte
5.22e27 >> 2^16
. Não há como brutar a força com tantas possibilidades.