Richtige Optionen für OpenSSL mit einfachem Geheimtext

Richtige Optionen für OpenSSL mit einfachem Geheimtext

Letztes Wochenende gab es eine kryptografische Herausforderung, bei der der Geheimtext der folgende Hex war:

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

Ich weiß mit Sicherheit, dass dies mit AES/Rijndael 128-Bit ECB verschlüsselt ist, der Schlüssel ist REDRYDER und eine Lösung dafür wurde bereits gepostet, um dies zu bestätigen. Der Klartext ist FLAG=DAISY. Ich habe ein einfaches PHP-mcrypt-Skript geschrieben, das dies ohne Salt oder IV-String entschlüsselt und es entschlüsselt richtig. Als ich jedoch versuchte, OpenSSL zu verwenden, erhielt ich nicht den Klartext:

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

Dies gibt nur einige Binärdaten aus. Ich habe auch versucht, die Eingabe durch dd conv=swab zu leiten, um einen Byte-Swap durchzuführen.

Was mache ich falsch?

Antwort1

Das opensslBefehlszeilentool ist eine Demo der OpenSSL-Bibliothek. Es hat eine ziemlich willkürliche Benutzeroberfläche und eine schlechte Dokumentation. Ich empfehle, es nur zum Testen der OpenSSL-Bibliothek zu verwenden. (Ja, es gibt Leute, die CAs mit verwalten openssl. Ich fürchte um ihre geistige Gesundheit.)

AESarbeitet mit einem Schlüssel, nicht mit einem Passwort. Ein AES-128-Schlüssel ist genau 16 Byte lang.

Die Option -knimmt keinen Schlüssel als Eingabe, sondern ein Passwort. Dieses Passwort wird gehasht, um einen Schlüssel abzuleiten; der Standardwert ist MD5 und kann mit der Befehlszeilenoption überschrieben werden -md. Soweit ich sehen kann, ist dies nicht im Handbuch dokumentiert, Sie müssen nur die Quelle lesen ( apps/enc.c, Aufruf von EVP_BytesToKey). Der MD5-Digest erzeugt aus jedem String einen 16-Byte-Wert, aber das wurde hier nicht verwendet. In diesem Fall ist der Schlüssel tatsächlich REDRYDER\0\0\0\0\0\0\0\0dort, wo die \0Null-Bytes sind.

Mit dieser Option -Kkönnen Sie einen Schlüssel in hexadezimaler Schreibweise übergeben. Wenn Sie weniger Bytes als die Schlüsselgröße übergeben, wird OpenSSL mit Nullbytes abgeschlossen. Um den Schlüssel zu übergeben REDRYDER\0\0\0\0\0\0\0\0, können Sie also $(echo REDRYDER | od -An -tx1 | tr -d ' ')Folgendes übergeben 5245445259444552: .

Die AES-128-ECB-Entschlüsselung des Geheimtextblocks FC89BFC2B05F1C2E64B8784392783AC9 mit dem Schlüssel 52454452594445520000000000000000 ergibt 464c41473d4441495359000000000000 (unter Verwendung von hexadezimalen Zahlen zur Darstellung der Bytefolgen). Das ist FLAG=DAISY\0\0\0\0\0\0.

Für kleine kryptographische Manipulationen wie diese bevorzuge ich die Python-Toplevel mit demPycryptoBibliothek.

>>> 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'

Antwort2

Das funktioniert:

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

Ich verstehe die Eingabe für die Option -k nicht, aber wenn Sie Ihren Klartextschlüssel in Hex umwandeln (korrekte Byte-Reihenfolge) und stattdessen -K verwenden, funktioniert es.

OpenSSL ist Voodoo!

verwandte Informationen