Datei hochladen
  1. base64hub
  2. Base64 im Code
  3. OpenSSL
Code

Base64 mit OpenSSL

openssl base64 gibt es auf fast jedem Linux-, macOS- und BSD-Rechner, und es verhält sich überall gleich. Es scheitert allerdings auch stillschweigend. Die Ausgaben unten stammen von OpenSSL 3.5.

Einen String kodieren und dekodieren

printf '%s' 'héllo wörld' | openssl base64        # aMOpbGxvIHfDtnJsZA==
echo 'aMOpbGxvIHfDtnJsZA==' | openssl base64 -d   # héllo wörld

openssl base64 ist die Kurzform von openssl enc -base64; beide Schreibweisen nehmen dieselben Optionen. Verwenden Sie beim Kodieren printf '%s', damit sich kein Zeilenumbruch in die Daten schleicht, und beim Dekodieren echo, aus dem Grund, der gleich folgt.

Die Zeilenumbruch-Falle und -A

Standardmäßig verarbeitet OpenSSL Base64 als Textzeilen, die mit einem Zeilenumbruch enden. Eine letzte Zeile ohne \n wird beim Dekodieren ignoriert, folgender Befehl gibt also überhaupt nichts aus:

printf 'aGVsbG8K' | openssl base64 -d             # (no output)
printf 'aGVsbG8K\n' | openssl base64 -d           # hello
printf 'aGVsbG8K' | openssl base64 -d -A          # hello

-A weist OpenSSL an, die ganze Eingabe als eine einzige Zeile zu behandeln. Verwenden Sie es in beide Richtungen:

  • Kodieren: Ohne -A wird die Ausgabe nach 64 Zeichen pro Zeile umgebrochen. Mit -A erhalten Sie eine Zeile, wie sie HTTP-Header, JSON und Umgebungsvariablen brauchen.
  • Dekodieren: Mit -A muss die Eingabe eine einzige Zeile ohne Zeilenumbrüche sein. Ohne -A lassen sich mehrzeilige Eingaben wie PEM-Inhalte problemlos dekodieren.
head -c 60 /dev/zero | tr '\0' x | openssl base64      # 64 chars, newline, 16 chars
head -c 60 /dev/zero | tr '\0' x | openssl base64 -A   # 80 chars on one line

Der Umbruch nach 64 Zeichen entspricht dem PEM-Format (RFC 7468), nicht MIME mit bis zu 76 Zeichen. Für MIME-Ausgaben eignen sich der MIME-Base64-Encoder oder GNU base64 (Standard 76) besser.

URL-sicheres Base64

OpenSSL hat keinen Base64URL-Modus. Übersetzen Sie mit tr:

printf '%s' '<<???>>' | openssl base64 -A | tr '+/' '-_' | tr -d '='
# PDw_Pz8-Pg

Zum Dekodieren kehren Sie die Zuordnung um und stellen das Padding wieder her; die Seite Base64 in Bash enthält eine Schleife dafür. OpenSSL selbst ignoriert - und _ stillschweigend, wie unten zu sehen, füttern Sie es also nie direkt mit URL-sicheren Eingaben. Base64 vs. Base64URL erklärt den Unterschied.

Dateien kodieren und dekodieren

openssl base64 -in photo.jpg -out photo.b64
openssl base64 -d -in photo.b64 -out photo-copy.jpg

OpenSSL arbeitet als Stream, große Dateien sind also kein Problem. Eine zufällige 100-KB-Datei überstand den Roundtrip Byte für Byte. Die kodierte Datei ist nach 64 Zeichen umgebrochen und endet mit einem Zeilenumbruch, das Dekodieren ohne -A funktioniert also. Brauchen Sie eine einzeilige Datei, ergänzen Sie -A beim Kodieren und noch einmal beim Dekodieren.

Für eine Data-URI:

printf 'data:image/jpeg;base64,%s' "$(openssl base64 -A -in photo.jpg)"

Der Abschnitt BUGS der enc-Manpage von OpenSSL 3.5 nennt weiterhin zwei verwandte Probleme: -A „doesn’t work properly“ bei großen Dateien, und beim Dekodieren ohne -A werden die ersten beiden Zeilen ignoriert, wenn die ersten 1024 Bytes der Eingabe keinen Zeilenumbruch enthalten. Eine große einzeilige Datei brechen Sie daher zuerst mit fold -w 64 um und dekodieren ohne -A.

Stille Fehler: das Ergebnis prüfen

OpenSSL meldet ungültiges Base64 nicht. Es hält bei den fehlerhaften Daten an, schreibt, was es bis dahin dekodiert hat, und endet mit Status 0. Ergebnisse mit OpenSSL 3.5:

EingabeAusgabeExit-Code
aGVsbG8K + Zeilenumbruchhello\n0
aGVsbG8K (ohne Zeilenumbruch)nichts0
aGk + Zeilenumbruch (ohne Padding)nichts0
aGk=!! + Zeilenumbruchnichts0
PDw_Pz8-Pg== + Zeilenumbruch (URL-sicher)nichts0
not base64 at all + Zeilenumbruchnichts0

Skripte müssen die Ausgabe deshalb selbst prüfen:

n=$(echo "$b64" | openssl base64 -d | wc -c)
[ "$n" -gt 0 ] || echo "decode failed or input was empty" >&2

Das erkennt vollständige Fehlschläge, aber keine teilweisen, bei denen OpenSSL ein Präfix dekodiert hat, bevor es auf fehlerhafte Daten stieß.

Oder Sie wechseln zu GNU base64 -d, das base64: invalid input ausgibt und mit 1 endet. Was mit einem bestimmten String nicht stimmt, zeigt der Base64-Validator, der das fehlerhafte Zeichen markiert; Häufige Base64-Fehler erklärt die Ursachen.

Hashes, Schlüssel und verschlüsselte Ausgabe

Meist wird Base64 in OpenSSL zusammen mit anderen Befehlen verwendet:

printf '%s' hi | openssl dgst -sha256 -binary | openssl base64 -A
# j0NDRmSPa5bfid2pAcUXaxCm2Dlh3TwayItZstwyeqQ=

openssl rand -base64 32          # 32 random bytes -> 44 characters

Die erste Form erzeugt SHA-256-Digests in Base64, wie sie SRI-Hashes und viele API-Signaturen verwenden; die Browser-Version ist das Tool SHA-256 in Base64. -binary ist wichtig: Ohne die Option kodieren Sie den Hex-Text des Hashs, nicht den Hash selbst.

openssl rand -base64 32 ist ein gängiger Weg, Secrets und Schlüssel zu erzeugen; der Base64-Schlüsselgenerator erledigt dasselbe im Browser.

openssl enc mit -a (gleichbedeutend mit -base64) kodiert den Chiffretext in Base64:

printf '%s' 'secret text' | openssl enc -aes-256-cbc -pbkdf2 -a -pass pass:demo
# U2FsdGVkX1/eMk5T8FT9dX8OyAxLRn/ukvgmovOQOeA=   (salt is random, changes every run)

Das Präfix U2FsdGVkX1 ist Base64 für Salted__. Ohne Passwort kommt beim Dekodieren nichts Lesbares heraus. Diesen Unterschied zwischen Kodieren und Verschlüsseln behandelt Kodierung vs. Verschlüsselung.

PEM-Dateien

Zertifikate und Schlüssel im PEM-Format sind Base64-kodiertes DER zwischen -----BEGIN ...------Zeilen, umgebrochen nach 64 Zeichen. OpenSSL wandelt sie direkt um, ganz ohne Base64-Handarbeit:

openssl x509 -in cert.pem -outform der -out cert.der
openssl x509 -in cert.der -inform der -outform pem

Um einen PEM-Block im Browser anzusehen, verwenden Sie den Zertifikat-Decoder oder PEM in DER.

Häufige Fragen

Warum gibt openssl base64 -d nichts aus?

Entweder fehlt der Eingabe der abschließende Zeilenumbruch, oder sie ist ungültig. Ohne -A erwartet OpenSSL Zeilen mit Zeilenumbruch und verwirft eine letzte Zeile ohne ihn kommentarlos. Ergänzen Sie -A oder geben Sie den String mit echo statt mit printf '%s' aus.

Ist openssl base64 dasselbe wie openssl enc -base64?

Ja. openssl base64 ist eine Abkürzung für openssl enc -base64, und beide akzeptieren -d, -A, -in und -out.

Wie prüfe ich, ob openssl base64 -d erfolgreich war?

Auf den Exit-Code können Sie sich nicht verlassen: Ungültige Eingaben liefern Status 0 mit leerer oder unvollständiger Ausgabe. Prüfen Sie, ob die Ausgabe nicht leer ist, oder verwenden Sie GNU base64 -d, das bei ungültiger Eingabe mit 1 endet.

Was bedeutet U2FsdGVkX1 am Anfang eines Base64-Strings?

Das ist das Base64 von Salted__, dem Header, den openssl enc bei Verwendung eines Passworts vor verschlüsselte Daten schreibt. Der String ist Chiffretext; beim Dekodieren erhalten Sie binäres Rauschen, nicht den Klartext.

Weiterlesen