Kann OpenSSL Base64-Daten dekodieren, die keine Zeilenumbrüche enthalten?

9

Ich habe zwei Blöcke von base64-Daten in einer Bash-Variablen. Die üblichen Zeilenumbrüche in den base64-Daten wurden durch Leerzeichen ersetzt, und die Variable ist im Grunde eine sehr lange einzeilige Zeichenfolge.

Ich kann die zwei in der Variablen enthaltenen Blöcke von base64-Daten dekodieren, aber ich habe beim Versuch einige Nuancen festgestellt. Ich würde gerne verstehen, ob ich mich dem richtig nähere oder ob es eine bessere Möglichkeit gibt, base64-Daten zu dekodieren, die keine Zeilenumbrüche enthalten. Folgendes habe ich:

Der erste Block besteht aus 350 Zeichen und ich kann ihn erfolgreich so dekodieren:

echo ${DATA::350} | openssl base64 -d | wc -c
256

Der zweite Block besteht aus 5745 Zeichen, aber der obige Befehl führt nicht zu den erwarteten Ergebnissen. dh:

$ echo {DATA:350} | openssl base64 -d | wc -c
432

Es funktioniert jedoch, wenn ich die Zeilenumbrüche zurückstelle:

$ echo ${DATA:350} | tr ' ' "\n" | openssl base64 -d | wc -c
4240

Ich gehe davon aus, dass es ein Problem mit der Zeilenlänge gibt, das der erste Block klein genug ist, um es zu vermeiden, und es scheint ein Merkmal des verwendeten base64-Decoders zu sein (die beiden üblichen base64und openssl base64verhalten sich unterschiedlich).

Der base64Decoder openssl base64stoppt (anstelle von ) beim ersten ungültigen Zeichen (dem Leerzeichen) und decodiert daher nur die erste "Zeile" (48 Byte Ausgabedaten), während OpenSSL 432 Zeichen (9 "Zeilen") ausgibt. Der base64Befehl verfügt über eine Option zum Ignorieren von Müll . Dies funktioniert also:

$ echo ${DATA:350} | base64 -d -i | wc -c
4240

Der OpenSSL-Decoder scheint keine solche Option zu haben.

Das Entfernen des Leerzeichens funktioniert auch vollständig für, base64aber nicht für openssl base64:

$ echo ${DATA:350} | tr -d ' ' | openssl base64 -d | wc -c
400

$ echo ${DATA:350} | tr -d ' ' | base64 -d | wc -c
4240

Am Ende habe ich also die Zeilenumbrüche ersetzt und den OpenSSL-Decoder verwendet, weil ich die decodierten Daten trotzdem weiterverarbeiten musste:

$ openssl enc -d -a -in <(echo ${DATA:350} | /usr/bin/tr ' ' "\n") -aes-256-cbc -pass file:<(echo $skey) | ...

Aber ich würde gerne verstehen, ob OpenSSL Base64-Daten dekodieren kann, die keine Zeilenumbrüche enthalten.

Sternenhimmel
quelle
FWIW bash kann sich ändern oder löschen Zeichen, ohne tr, mit ${var//old[/new}- aber nicht zur gleichen Zeit wie substringing.
Dave_thompson_085

Antworten:

17

Wenn Sie keine Leerzeichen benötigen , opensslwird dies mit der folgenden -AOption behandelt:

Damit:

$ ls -l sp2.bmp
-rw-r--r-- 1 sweh sweh 3000054 Apr 21 20:13 sp2.bmp
$ x=$(openssl base64 -A < sp2.bmp)                
$ echo "$x" | wc
      1       1 4000073
$ echo "$x" | openssl base64 -d -A > res
$ ls -l res
-rw-r--r-- 1 sweh sweh 3000054 Jul 30 10:00 res
$ cmp res sp2.bmp 
$ 

Wir können sehen, dass sich die base64-Daten alle in einer Zeile befinden und dekodiert werden können.

man encerklärt die -AOption.

Wenn Sie die Leerzeichen behalten müssen, müssen Sie sie entfernen (entweder durch Konvertieren in '\n'oder durch Löschen und Verwenden -A).

Stephen Harris
quelle
Die -AOption war eines der ersten Dinge, die ich ausprobiert habe, aber ich habe dies getan, bevor ich versucht habe, die Leerzeichen zu entfernen, und bin dann "weitergegangen", wenn es nicht funktioniert hat! In der Manpage wird nichts darüber erwähnt, dass Leerzeichen ein Problem darstellen. Wie auch immer, ich habe es gerade noch einmal versucht, wobei die Leerzeichen entfernt wurden und es funktioniert. Es ist immer noch böse, aber zumindest ist es nur eine tr -d ' '. Es ist eine Schande, dass es nicht verarbeitet werden kann und das Leerzeichen ignoriert (wie base64kann).
Sternenfrucht
2
RFC 4648 besagt, dass streng genommen Leerzeichen (Abschnitt 3.3) und Zeilenvorschübe (Abschnitt 3.1) in base64 verboten sind. In Abschnitt 3.3 heißt es auch, dass Implementierungen in diesem Fall Daten ablehnen MÜSSEN. Ist openssl base64 -Aalso näher an einer strengen Interpretation, die Sie von einem Sicherheitsverschlüsselungstool erwarten würden. Ich denke, die Coreutils base64sind milder.
Stephen Harris
1
OpenSSL implementierte base64 in den 1990er Jahren (vor 4648 oder sogar 3548) hauptsächlich zum Lesen und Schreiben von 'PEM'- (wirklich PEM-ähnlichen) und S / MIME-Dateien, die beide Zeilenumbrüche erfordern. -Aist im Grunde "wir haben die EVP_{En,De}codeBlockFaktoren, könnten genauso gut die Leute sie benutzen lassen".
Dave_thompson_085