Verschlüsselungskompatibilität zwischen TCL und OpenSSL

Verschlüsselungskompatibilität zwischen TCL und OpenSSL

Ich habe ein Shell-Skript und ein TCL-Skript, die einen Verschlüsselungsmechanismus verwenden, und möchte von beiden Skripten die gleiche verschlüsselte Ausgabe erhalten.

Beispielsweise sollte die Ausgabeverschlüsselung des Tcl-Skripts und des Shell-Skripts identisch sein. Der Verschlüsselungsmechanismus, den ich verwenden möchte, ist entweder AES oder DES. (Und ich bin grundsätzlich offen für die Verwendung jedes Verschlüsselungsmechanismus.)

Das Problem besteht darin, dass beide Skripte unterschiedliche Geheimtexte erzeugen.

In tcl verwende ich den folgenden Befehl:

[aes::aes -mode cbc -dir encrypt -key 1234567891012345 hi]

und im Shell-Skript:

echo -n "hi" | openssl enc -aes-128-cbc -nosalt -pass pass:1234567891012345

Ich ging davon aus, dass das Ergebnis beider Befehle das gleiche sein würde, aber das ist nicht der Fall. Ich verwende keine Salt-Option, sodass dieselbe Chiffre vom Shell-Skript generiert wird, wenn der Befehl zweimal ausgeführt wird.

Gibt es eine Möglichkeit, mit unterschiedlichen Skripten denselben Geheimtext zu erhalten?

Antwort1

Wenn Sie openssl encdie Verwendung einer Passphrase angeben, wird diese immer über einen KDF eingespeist und nie direkt als Schlüssel verwendet. -nosaltDies wird durch die Verwendung nicht deaktiviert. (Sie können die openssl enc -pOption verwenden, um zu sehen, welcher Schlüssel und IV tatsächlich verwendet wird.)Um einen Rohschlüssel anzugeben, benötigen Sie die -KOption.

(Beachten Sie, dass openssl enc -Kder Wert voraussichtlichin hexadezimal,wird in der Zwischenzeit aes::aes -keyals Rohbinärdaten interpretiert.)

Das andere Problem ist das Auffüllen. Da AES eine Blockchiffre ist,alle Eingabedaten müssen aufgefüllt werdenauf ein Vielfaches von 16 Bytes (die AES-Blockgröße) und es gibt mehrere Auffüllmethoden mit unterschiedlichen Sicherheitseigenschaften. Das Tcl- aesModul verwendet einfaches Auffüllen mit Nullen und erweitert die Daten mit 0x00 Bytes.

OpenSSL verwendet inzwischen PKCS#7-Padding und füllt den Block mit einem Wert, der der Pad-Größe entspricht. Wenn Ihre Eingabe beispielsweise nur 2 Bytes umfasst, sind 14 Bytes Padding erforderlich, sodass gemäß PKCS#7 jedes Pad-Byte ebenfalls den Wert 14 (0x0E) hat.

( man encspricht von PKCS#5, einem älteren Dokument, das das Füllschema nur für 8-Byte-Blöcke definiert. PKCS#7 definierte später genau dasselbe Schemafür jede Blockgröße.)

Für den CBC-Modus müssen Sie außerdemGeben Sie einen IV an(16 Bytes, entspricht der AES-Blockgröße). Das Tcl-Modul verwendet standardmäßig einen IV, der nur aus Nullen besteht. CBC verwendet den IV jedoch nur für den 2. und spätere Blöcke, sodass die Ausgabe für kurzen Text nicht beeinflusst wird.

Zusammenfassend lässt sich also sagen, dass Sie mit diesen Ergebnissen identische Ergebnisse erzielen (unter Verwendung von Null-Padding):

aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex "hi"

printf 'hi\0\0\0\0\0\0\0\0\0\0\0\0\0\0' \
  | openssl enc -aes-128-cbc -nopad \
    -K 31323334353637383931303132333435 \
    -iv 00000000000000000000000000000000 \
  | hexdump -C

Auch diese (mit PKCS#7-Padding):

aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex \
         "hi\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e"

printf 'hi' \
  | openssl enc -aes-128-cbc \
    -K 31323334353637383931303132333435 \
    -iv 00000000000000000000000000000000 \
  | hexdump -C

So implementieren Sie die Polsterung:

set data "hi"
set pad [expr {16 - ([string length $data] % 16)}]
append data [string repeat [format %c $pad] $pad]
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex $data

verwandte Informationen