
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 enc
die Verwendung einer Passphrase angeben, wird diese immer über einen KDF eingespeist und nie direkt als Schlüssel verwendet. -nosalt
Dies wird durch die Verwendung nicht deaktiviert. (Sie können die openssl enc -p
Option verwenden, um zu sehen, welcher Schlüssel und IV tatsächlich verwendet wird.)Um einen Rohschlüssel anzugeben, benötigen Sie die -K
Option.
(Beachten Sie, dass openssl enc -K
der Wert voraussichtlichin hexadezimal,wird in der Zwischenzeit aes::aes -key
als 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- aes
Modul 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 enc
spricht 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