Opções adequadas para openssl com texto cifrado simples

Opções adequadas para openssl com texto cifrado simples

No fim de semana passado houve um desafio criptográfico onde o texto cifrado era o seguinte hexadecimal:

FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9

Tenho certeza de que isso é criptografado usando BCE AES/Rijndael de 128 bits, a chave é REDRYDER e uma solução para isso já foi postada para confirmar isso. O texto simples é FLAG=DAISY. Eu escrevi um script PHP mcrypt simples que descriptografa isso sem sal ou sem string IV e descriptografa corretamente. No entanto, quando tentei usar o openssl, não recebo o texto simples:

echo "0: FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9" | xxd -r | openssl aes-128-ecb -d -k REDRYDER -nosalt -nopad ; echo

Isso apenas gera alguns dados binários. Também tentei passar a entrada por dd conv=swab para fazer uma troca de bytes.

O que estou fazendo de errado?

Responder1

A opensslferramenta de linha de comando é uma demonstração da biblioteca OpenSSL. Possui uma interface bastante aleatória e documentação deficiente. Não recomendo usá-lo para outra coisa senão testar a biblioteca OpenSSL. (Sim, existem pessoas que gerenciam CAs com openssl. Temo por sua sanidade.)

AESopera com uma chave, não com uma senha. Uma chave AES-128 tem exatamente 16 bytes.

A opção -knão aceita uma chave como entrada, mas sim uma senha. Essa senha é criptografada para derivar uma chave; o padrão é MD5 e pode ser substituído pela opção de linha de comando -md. Até onde posso ver, isso não está documentado no manual, basta ler a fonte ( apps/enc.c, ligar para EVP_BytesToKey). O resumo MD5 produz um valor de 16 bytes de qualquer string, mas não foi isso que foi usado aqui. Nesse caso, a chave está na verdade REDRYDER\0\0\0\0\0\0\0\0onde \0estão os bytes nulos.

A opção -Kpermite passar uma chave, em hexadecimal. Se você passar menos bytes que o tamanho da chave, o OpenSSL será concluído com bytes nulos. Então, para passar a chave REDRYDER\0\0\0\0\0\0\0\0, você pode passar $(echo REDRYDER | od -An -tx1 | tr -d ' ')qual é 5245445259444552.

A operação de descriptografia AES-128-ECB do bloco de texto cifrado FC89BFC2B05F1C2E64B8784392783AC9 com a chave 52454452594445520000000000000000 produz 464c41473d4441495359000000000000 (usando ele xadecimal para representar as sequências de bytes). Isso é FLAG=DAISY\0\0\0\0\0\0.

Para pequenas manipulações criptográficas como essas, gosto do nível superior do Python com oPycryptobiblioteca.

>>> from binascii import hexlify, unhexlify
>>> from Crypto.Cipher import AES
>>> ciphertext = unhexlify('FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9'.replace(' ', ''))
>>> key = 'REDRYDER'.ljust(16, '\0')
>>> AES.new(key, AES.MODE_ECB).decrypt(ciphertext)
'FLAG=DAISY\x00\x00\x00\x00\x00\x00'

Responder2

Isso funciona:

echo '0: FC89BFC2B05F1C2E64B8784392783AC9' | xxd -r | openssl enc -aes-128-ecb -d -nopad -nosalt -K 5245445259444552

Não entendo a entrada da opção -k, mas se você converter sua chave de texto simples em hexadecimal (ordenação adequada de bytes) e usar -K, ela funcionará.

openssl é vodu!

informação relacionada