Esse desafio carrega uma recompensa de 200 pontos para o primeiro responder e permanece invicto por pelo menos 3 dias.Reivindicada pelo usuário3080953 .
Ultimamente, há muita conversa sobre criptografia de ponta a ponta e pressão sobre as empresas para removê-la de seus produtos. Não estou interessado nos erros e desvantagens disso, mas me perguntei: quão curto pode ser o código que levaria uma empresa a ser pressionada a não usá-lo?
O desafio aqui é implementar uma troca de chaves Diffie Hellman entre dois sistemas em rede e permitir que os usuários se comuniquem alternadamente usando a chave simétrica gerada. Para o objetivo desta tarefa, nenhuma outra proteção é necessária (por exemplo, não é necessário alternar a chave, verificar identidades, proteger contra DoS etc.) e você pode assumir uma Internet aberta (todas as portas que você escuta estão disponíveis para todos). O uso de componentes internos é permitido e incentivado!
Você pode escolher um dos dois modelos:
- Um servidor e um cliente: o cliente se conecta ao servidor, então o servidor ou o cliente pode enviar mensagens para o outro. Terceiros entre os dois devem ser incapazes de ler as mensagens. Um exemplo de fluxo pode ser:
- O usuário A inicia o servidor
- O usuário B inicia o cliente e o direciona para o servidor do usuário A (por exemplo, via IP / porta), o programa abre uma conexão
- O programa do usuário A reconhece a conexão (opcionalmente, solicitando o consentimento do usuário primeiro)
- O programa do usuário B inicia a geração de um segredo DH e envia os dados necessários (chave pública, prime, gerador, qualquer outra coisa que sua implementação precise) ao usuário A
- O programa do Usuário A usa os dados enviados para concluir a geração do segredo compartilhado e envia de volta os dados necessários (chave pública) ao Usuário B. A partir deste ponto, o Usuário A pode inserir mensagens (por exemplo, via stdin) que serão criptografadas e enviadas ao Usuário. B (por exemplo, stdout).
- O programa do usuário B completa a geração do segredo compartilhado. A partir deste ponto, o usuário B pode enviar mensagens para o usuário A.
- Ou: um servidor com dois clientes conectados a ele: cada cliente conversa com o servidor, que encaminha sua mensagem para o outro cliente. O próprio servidor (e quaisquer terceiros intermediários) deve ser incapaz de ler as mensagens. Além da conexão inicial, o processo é o mesmo descrito na primeira opção.
Regras detalhadas:
- Você pode fornecer um único programa ou vários programas (por exemplo, servidor e cliente). Sua pontuação é o tamanho total do código em todos os programas.
- Seu programa deve ser teoricamente capaz de se comunicar através de uma rede (mas, para testar, o host local é bom). Se o seu idioma de escolha não suportar redes, você pode combiná-lo com algo que o faça (por exemplo, um shell script); nesse caso, sua pontuação é o tamanho total do código em todos os idiomas usados.
- A geração de chaves Diffie Hellman pode usar valores "p" e "g" codificados.
- A chave compartilhada gerada deve ter pelo menos 1024 bits.
- Depois que a chave é compartilhada, a escolha da criptografia de chave simétrica depende de você, mas você não deve escolher um método que atualmente é conhecido por ter um ataque prático contra ela (por exemplo, um deslocamento de césar é trivial para reverter sem o conhecimento da chave ) Exemplo de algoritmos permitidos:
- AES (qualquer tamanho de chave)
- RC4 (teoricamente quebrado, mas nenhum ataque prático que eu possa encontrar menção, por isso é permitido aqui)
- Os usuários A e B devem poder enviar mensagens um para o outro (comunicação bidirecional) interativamente (por exemplo, lendo linhas de stdin, solicitações contínuas ou eventos como pressionar um botão). Se facilitar, você pode assumir uma conversa alternada (ou seja, depois que um usuário envia uma mensagem, ele deve aguardar uma resposta antes de enviar a próxima mensagem)
- Os idiomas embutidos são permitidos (não é necessário escrever seus próprios métodos criptográficos ou de rede, se já tiverem suporte).
- O formato de comunicação subjacente é com você.
- As etapas de comunicação fornecidas acima são um exemplo, mas você não precisa segui-las (desde que as informações necessárias sejam compartilhadas e nenhum intermediário seja capaz de calcular a chave ou as mensagens compartilhadas)
- Se os detalhes necessários para conectar-se ao seu servidor não forem conhecidos antecipadamente (por exemplo, se ele escutar em uma porta aleatória), esses detalhes deverão ser impressos. Você pode assumir que o endereço IP da máquina é conhecido.
- O tratamento de erros (por exemplo, endereços inválidos, conexões perdidas etc.) não é necessário.
- O desafio é o código de golfe, portanto o código mais curto em bytes vence.
p
eg
permitido?Respostas:
Node.js (
372423 + 94 = 517513 bytes)Golfe
Quebras de linha adicionadas para "legibilidade".
chat.js (
423419 bytes)Sem quebras de linha
Quebras de linha
echo_server.js (94 bytes)
Ungolfed
O nó possui recursos integrados de rede e criptografia. Isso usa o TCP para redes (porque é mais simples que a interface do Node para HTTP e funciona muito bem com fluxos).
Eu uso uma cifra de fluxo (RC4) em vez do AES para evitar ter que lidar com tamanhos de bloco. A Wikipedia parece achar que pode ser vulnerável; portanto, se alguém tiver alguma ideia sobre quais são as cifras preferidas, isso seria ótimo.
Execute o servidor de eco
node echo_server.js
que escutará na porta 9. Execute duas instâncias deste programa comnode chat.js <server IP>
enode chat.js <server IP> 1
(o último argumento apenas define qual deles envia um prime). Cada instância se conecta ao servidor de eco. A primeira mensagem lida com a geração de chaves e as mensagens subseqüentes usam a cifra de fluxo.O servidor de eco apenas envia tudo de volta a todos os clientes conectados, exceto o original.
Cliente
Servidor de eco
Obrigado Dave por todas as dicas + feedback!
fonte
Node.js,
638607 bytesAgora que foi bem derrotado (e no mesmo idioma), eis a minha resposta de teste:
Ou com embalagem:
Uso
Esta é uma implementação de servidor / cliente; uma instanciação será o servidor e a outra o cliente. O servidor é iniciado com uma porta específica e, em seguida, o cliente é apontado para a porta do servidor. A DH pode levar alguns segundos para ser configurada se a máquina estiver com pouca entropia, portanto, as primeiras mensagens podem demorar um pouco.
Demolir
O único requisito para os tokens é que eles contenham pelo menos um caractere não hexadecimal, portanto, no código minificado, outras constantes de string são usadas (
data
ehex
).fonte