Base64 in Go dekodieren — encoding/base64 + Beispiele

·Systems Engineer·Geprüft vonHana Nováková·Veröffentlicht

Nutze das kostenlose Base64 Decode Online direkt im Browser – keine Installation erforderlich.

Base64 Decode Online online testen →

Base64-Decodierung in Go begegnet einem ständig — JWT-Inspektion, binäre Dateianhänge, API-Payloads von Cloud-Diensten. Das Standard-Paket encoding/base64von Go deckt all das ab, aber die Wahl der falschen Kodierungsvariante (Standard vs. URL-sicher, mit oder ohne Padding) ist die häufigste Ursache für “illegal base64 data”-Fehler. Dieser Leitfaden behandelt StdEncoding, URLEncoding, RawURLEncoding, Streaming-Decodierung mit base64.NewDecoder, JWT-Payload-Inspektion und vier Fehler, über die fast jeder beim ersten Mal stolpert. Für einmalige Decodierungen im Browser erledigt ToolDeck's Base64 Decoder den Job sofort, ohne eine einzige Zeile Code schreiben zu müssen.

  • encoding/base64 ist Teil der Go-Standardbibliothek — kein go get erforderlich
  • RawURLEncoding für JWT-Tokens und die meisten modernen APIs verwenden (kein Padding, URL-sicheres Alphabet)
  • StdEncoding verwendet + und / mit =-Padding; URLEncoding wechselt zu - und _, behält aber das Padding
  • base64.NewDecoder umschließt jeden io.Reader für Streaming-Decodierung ohne Laden in den Speicher
  • Den zurückgegebenen Fehler immer prüfen — ungültiges Padding und falsches Alphabet erzeugen "illegal base64 data"

Was ist Base64-Decodierung?

Base64-Kodierung stellt Binärdaten als ASCII-Text dar, indem 64 druckbare Zeichen (A–Z, a–z, 0–9 plus zwei weitere) verwendet werden. Die Decodierung kehrt diesen Vorgang um — sie wandelt die ASCII-Darstellung zurück in die ursprünglichen Bytes. Jeweils 4 Base64-Zeichen decodieren zu genau 3 Bytes. Das Verfahren existiert, weil viele Transportschichten (E-Mail, HTTP-Header, JSON-Felder) für Text und nicht für rohe Binärdaten ausgelegt sind. So sieht der vollständige Roundtrip aus:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// Rohe Bytes → Base64-kodiert → zurück zu rohen Bytes decodiert
	original := []byte("service_token:xK9mP2qR")
	// Kodiert: "c2VydmljZV90b2tlbjp4SzltUDJxUg=="

	encoded := base64.StdEncoding.EncodeToString(original)
	decoded, _ := base64.StdEncoding.DecodeString(encoded)
	fmt.Println(string(decoded) == string(original)) // true
}

Base64 in Go mit encoding/base64 decodieren

Das Paket encoding/base64 wird mit Go ausgeliefert — keine externen Abhängigkeiten. Es stellt vier vordefinierte Kodierungsvarianten als Variablen auf Paketebene bereit. Die am häufigsten verwendete Funktion für String-Eingaben ist DecodeString, die ein Byte-Slice und einen Fehler zurückgibt.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	// Standard-Base64 — das Alphabet verwendet + und / mit =-Padding
	encoded := "eyJob3N0IjoiZGItcHJvZCF1cy1lYXN0LTEiLCJwb3J0Ijo1NDMyfQ=="
	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode error: %v", err)
	}
	fmt.Println(string(decoded))
	// {"host":"db-prod.us-east-1","port":5432}
}

Die Methode Decode arbeitet mit Byte-Slices statt mit Strings und schreibt das Ergebnis in einen vorab allokierten Zielpuffer. Die Puffergröße muss korrekt bestimmt werden — mit base64.StdEncoding.DecodedLen(len(src)) die maximale Größe ermitteln (sie kann aufgrund des Paddings einige Bytes größer als die tatsächliche decodierte Länge sein).

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	src := []byte("eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9")
	dst := make([]byte, base64.RawStdEncoding.DecodedLen(len(src)))

	n, err := base64.RawStdEncoding.Decode(dst, src)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(dst[:n]))
	// {"host":"db-prod","port":5432}
}
Hinweis:DecodedLen gibt eine obere Schranke zurück, nicht die exakte Länge. Den Rückgabewert n von Decode immer verwenden, um das Ergebnis korrekt zu schneiden: dst[:n].

StdEncoding vs. URLEncoding — Die richtige Variante wählen

Hier entsteht die meiste Verwirrung. Das Paket encoding/base64 von Go stellt vier Kodierungsobjekte bereit, und die Wahl des falschen führt garantiert zu einem Fehler. Der Unterschied beruht auf zwei Dingen: dem Alphabet und dem Padding.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// JWT-Header-Payload — URL-sicher, kein Padding
	jwtHeader := "eyJhbGciOiJSUzI1NiIsImtpZCI6IjIwMjMtMDkifQ"

	// Falsch: StdEncoding schlägt bei URL-sicherer Eingabe ohne Padding fehl
	_, err1 := base64.StdEncoding.DecodeString(jwtHeader)
	fmt.Println("StdEncoding error:", err1)
	// StdEncoding error: illegal base64 data at input byte 43

	// Richtig: RawURLEncoding — kein Padding, URL-sicheres Alphabet
	decoded, err2 := base64.RawURLEncoding.DecodeString(jwtHeader)
	fmt.Println("RawURLEncoding ok:", err2, "→", string(decoded))
	// RawURLEncoding ok: <nil> → {"alg":"RS256","kid":"2023-09"}
}

Die vier Varianten im Überblick:

Funktion / Methode
Kodierung
Padding erforderlich
Rückgabe
base64.StdEncoding.DecodeString(s)
Standard (+, /)
Ja (=)
([]byte, error)
base64.URLEncoding.DecodeString(s)
URL-sicher (-, _)
Ja (=)
([]byte, error)
base64.RawStdEncoding.DecodeString(s)
Standard (+, /)
Nein
([]byte, error)
base64.RawURLEncoding.DecodeString(s)
URL-sicher (-, _)
Nein
([]byte, error)
base64.StdEncoding.Decode(dst, src)
Standard (+, /)
Ja (=)
(n int, error)
base64.NewDecoder(enc, r)
Beliebige Kodierung
Ja
io.Reader

Meine Faustregel: Kommt der Wert von einem JWT, einem OAuth-Flow oder einem Cloud-Provider-SDK, zuerst RawURLEncoding verwenden. Kommt er aus E-Mail-Anhängen oder klassischen Web-Formularen, StdEncoding probieren. Die Fehlermeldung nennt immer die genaue Byte-Position, an der die Decodierung fehlgeschlagen ist.

Base64 aus Datei und API-Antwort decodieren

Eine Base64-kodierte Datei lesen

Binärdateien (Bilder, PDFs, Zertifikate) werden manchmal Base64-kodiert auf der Festplatte gespeichert. Datei einlesen, abschließende Leerzeichen entfernen, dann decodieren:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"os"
	"strings"
)

func main() {
	raw, err := os.ReadFile("certificate.pem.b64")
	if err != nil {
		log.Fatalf("read file: %v", err)
	}

	// Zeilenumbrüche entfernen — Base64-Dateien haben oft Zeilenumbrüche alle 76 Zeichen
	cleaned := strings.ReplaceAll(strings.TrimSpace(string(raw)), "\n", "")

	decoded, err := base64.StdEncoding.DecodeString(cleaned)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}

	if err := os.WriteFile("certificate.pem", decoded, 0600); err != nil {
		log.Fatalf("write: %v", err)
	}
	fmt.Printf("decoded %d bytes → certificate.pem\n", len(decoded))
}

Ein Base64-Feld aus einer JSON-API-Antwort decodieren

Cloud-APIs geben Binärdaten (Verschlüsselungsschlüssel, signierte Blobs, Thumbnails) häufig als Base64-Strings innerhalb von JSON zurück. Zuerst das JSON unmarshalen, dann das Zielfeld decodieren:

Go 1.21+
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

type SecretResponse struct {
	Name    string `json:"name"`
	Payload string `json:"payload"` // Base64-kodierter Secret-Wert
	Version int    `json:"version"`
}

func fetchAndDecodeSecret(secretURL string) ([]byte, error) {
	resp, err := http.Get(secretURL)
	if err != nil {
		return nil, fmt.Errorf("http get: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
	}

	var secret SecretResponse
	if err := json.NewDecoder(resp.Body).Decode(&secret); err != nil {
		return nil, fmt.Errorf("decode json: %w", err)
	}

	value, err := base64.StdEncoding.DecodeString(secret.Payload)
	if err != nil {
		return nil, fmt.Errorf("decode base64: %w", err)
	}
	return value, nil
}

func main() {
	value, err := fetchAndDecodeSecret("https://api.example.com/secrets/db-password")
	if err != nil {
		log.Fatalf("fetch secret: %v", err)
	}
	fmt.Printf("secret value: %s\n", value)
}
Hinweis:Fehler mit fmt.Errorf("decode base64: %w", err) einwickeln, anstatt Kontext zu verlieren. Die ursprüngliche Fehlermeldung von encoding/base64 enthält die Byte-Position des Fehlers, was beim Debuggen hilfreich ist.

Große Base64-kodierte Dateien per Streaming decodieren

Eine 500-MB-Base64-kodierte Datei mit os.ReadFile in den Speicher laden und dann DecodeString aufrufen, verbraucht rund 750 MB RAM (der kodierte String plus die decodierten Bytes). base64.NewDecoder umschließt jeden io.Reader und decodiert in Chunks, wodurch der Speicherverbrauch nahezu konstant bleibt. In Kombination mit io.Copy ergibt sich eine saubere Streaming-Pipeline:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"io"
	"log"
	"os"
)

func streamDecodeFile(srcPath, dstPath string) error {
	src, err := os.Open(srcPath)
	if err != nil {
		return fmt.Errorf("open source: %w", err)
	}
	defer src.Close()

	dst, err := os.Create(dstPath)
	if err != nil {
		return fmt.Errorf("create dest: %w", err)
	}
	defer dst.Close()

	decoder := base64.NewDecoder(base64.StdEncoding, src)
	written, err := io.Copy(dst, decoder)
	if err != nil {
		return fmt.Errorf("stream decode: %w", err)
	}
	fmt.Printf("written %d bytes to %s\n", written, dstPath)
	return nil
}

func main() {
	if err := streamDecodeFile("backup.tar.b64", "backup.tar"); err != nil {
		log.Fatal(err)
	}
}
Warnung:base64.NewDecoder erwartet saubere, ununterbrochene Base64-Daten. Enthält die Quelldatei Zeilenumbrüche (üblich in PEM- und MIME-kodierten Dateien), den Quell-Reader mit einem zeilenentfernenden Reader umschließen oder die Datei vorher bereinigen, bevor mit dem Streaming begonnen wird.

Base64-Decodierung über die Befehlszeile

Die meisten Go-Entwickler greifen beim Debuggen zuerst zur Befehlszeile. Jedes macOS- und Linux-System liefert base64 mit; unter Windows bietet PowerShell ein integriertes Äquivalent. Für die schnelle Inspektion von API-Payloads sind diese Methoden schneller als das Schreiben eines Go-Skripts.

bash
# Einen Base64-String decodieren (Linux / macOS)
echo "eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9" | base64 --decode
# {"host":"db-prod","port":5432}

# Decodieren und mit jq formatiert ausgeben (JSON-Ausgabe pipen)
echo "eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9" | base64 --decode | jq .
# {
#   "host": "db-prod",
#   "port": 5432
# }

# Eine Base64-kodierte Datei zu Binär decodieren
base64 --decode < encrypted_payload.b64 > encrypted_payload.bin

# macOS verwendet -D statt --decode
echo "c2VjcmV0LXRva2Vu" | base64 -D

Für die Inspektion von JWT-Tokens ohne installierte Tools den Token in ToolDeck's Base64 Decoder einfügen — an den Punkten aufteilen und jeden Teil einzeln decodieren.

Hochleistungsalternative: encoding/base64 ist bereits schnell

Anders als in Python, wo orjson vs. json ein relevantes Performance-Thema ist, ist das Paket encoding/base64 von Go bereits assembly-optimiert und für die meisten Anwendungsfälle genuinen schnell. Wer allerdings Millionen von Datensätzen in einer engen Schleife verarbeitet, für den bietet filippo.io/base64 SIMD-beschleunigte Decodierung mit einer Drop-in-API.

bash
go get filippo.io/base64
Go 1.21+
package main

import (
	"fmt"
	"log"

	"filippo.io/base64"
)

func main() {
	// Drop-in-Ersatz — gleiche API wie encoding/base64
	encoded := "eyJob3N0IjoiY2FjaGUtcHJvZCIsInBvcnQiOjYzNzl9"
	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(decoded))
	// {"host":"cache-prod","port":6379}
}

Der Performance-Gewinn ist am deutlichsten auf amd64 mit AVX2-Unterstützung — Benchmarks zeigen einen 2- bis 4-fachen Durchsatzgewinn bei großen Eingaben. Für alltägliche API-Antwort-Decodierungen (jeweils einige hundert Bytes) bleibt die Standardbibliothek die richtige Wahl.

Base64-JWT-Payload in Go decodieren

JWT-Inspektion kommt in nahezu jedem Backend-Dienst vor. In meiner Erfahrung läuft die meiste Debugging-Arbeit auf die Frage hinaus: “Was steckt eigentlich in diesem Token?” — und das lässt sich ohne eine vollwertige JWT-Bibliothek beantworten. Der Token besteht aus drei Base64url-kodierten Segmenten, die durch Punkte getrennt sind. Das mittlere Segment ist der Payload, auf den es wirklich ankommt:

Go 1.21+
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"log"
	"strings"
)

type JWTPayload struct {
	Subject  string   `json:"sub"`
	Issuer   string   `json:"iss"`
	Expiry   int64    `json:"exp"`
	Roles    []string `json:"roles"`
}

func decodeJWTPayload(token string) (*JWTPayload, error) {
	parts := strings.Split(token, ".")
	if len(parts) != 3 {
		return nil, fmt.Errorf("invalid JWT: expected 3 segments, got %d", len(parts))
	}

	// JWT verwendet RawURLEncoding — URL-sicheres Alphabet, kein =-Padding
	raw, err := base64.RawURLEncoding.DecodeString(parts[1])
	if err != nil {
		return nil, fmt.Errorf("decode payload: %w", err)
	}

	var payload JWTPayload
	if err := json.Unmarshal(raw, &payload); err != nil {
		return nil, fmt.Errorf("unmarshal payload: %w", err)
	}
	return &payload, nil
}

func main() {
	token := "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3ItNDQyIiwiaXNzIjoiYXV0aC5leGFtcGxlLmNvbSIsImV4cCI6MTc0MTk1NjgwMCwicm9sZXMiOlsiYWRtaW4iLCJhdWRpdG9yIl19.SIGNATURE"

	payload, err := decodeJWTPayload(token)
	if err != nil {
		log.Fatalf("jwt: %v", err)
	}
	fmt.Printf("Subject: %s\n", payload.Subject)
	fmt.Printf("Issuer:  %s\n", payload.Issuer)
	fmt.Printf("Roles:   %v\n", payload.Roles)
	// Subject: usr-442
	// Issuer:  auth.example.com
	// Roles:   [admin auditor]
}

Häufige Fehler

Alle vier dieser Fehler sind mir in echten Code-Reviews begegnet — die ersten beiden tauchen fast jedes Mal auf, wenn jemand einen neuen Auth-Provider integriert.

StdEncoding auf URL-sichere Eingabe anwenden

Problem: JWT-Tokens und OAuth-Tokens verwenden das URL-sichere Base64-Alphabet (- und _). Sie an StdEncoding.DecodeString zu übergeben, schlägt mit 'illegal base64 data' fehl.

Lösung: Die Eingabequelle prüfen: Tokens von Auth-Systemen verwenden RawURLEncoding; Binäranhänge verwenden StdEncoding.

Before · Go
After · Go
// JWT-Header — URL-sicher, kein Padding
token := "eyJhbGciOiJSUzI1NiJ9"
decoded, err := base64.StdEncoding.DecodeString(token)
// err: illegal base64 data at input byte 19
// JWT-Header — korrekte Kodierung
token := "eyJhbGciOiJSUzI1NiJ9"
decoded, err := base64.RawURLEncoding.DecodeString(token)
// decoded: {"alg":"RS256"}
// err: nil
Den Rückgabewert n von Decode ignorieren

Problem: Decode schreibt in einen vorab allokierten Puffer und gibt die Anzahl der tatsächlich geschriebenen Bytes zurück. DecodedLen gibt eine obere Schranke zurück, sodass das Ende des Puffers Garbage-Bytes enthalten kann.

Lösung: Das Ergebnis immer mit dst[:n] schneiden — nicht mit dst[:len(dst)].

Before · Go
After · Go
dst := make([]byte, base64.StdEncoding.DecodedLen(len(src)))
base64.StdEncoding.Decode(dst, src)
fmt.Println(string(dst)) // kann abschließende Null-Bytes enthalten
dst := make([]byte, base64.StdEncoding.DecodedLen(len(src)))
n, err := base64.StdEncoding.Decode(dst, src)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(dst[:n])) // korrekt — nur die decodierten Bytes
Leerzeichen vor dem Decodieren nicht entfernen

Problem: Base64-Strings, die aus Terminals, E-Mails oder Config-Dateien kopiert wurden, haben oft abschließende Zeilenumbrüche oder Leerzeichen. Sie direkt an DecodeString zu übergeben, schlägt am Leerzeichen-Zeichen fehl.

Lösung: strings.TrimSpace (und strings.ReplaceAll für eingebettete Zeilenumbrüche) vor dem Decodieren aufrufen.

Before · Go
After · Go
// Wert aus einer Config-Datei mit abschließendem Zeilenumbruch
encoded := "c2VydmljZV9rZXk6eEtNcDI=\n"
decoded, err := base64.StdEncoding.DecodeString(encoded)
// err: illegal base64 data at input byte 24
encoded := "c2VydmljZV9rZXk6eEtNcDI=\n"
cleaned := strings.TrimSpace(encoded)
decoded, err := base64.StdEncoding.DecodeString(cleaned)
// decoded: "service_key:xKMp2"
// err: nil
Decodierte Bytes falsch als String speichern

Problem: string(decoded) auf Binärdaten (Bilder, komprimierte Payloads) anzuwenden, erzeugt ungültige UTF-8-Strings. Go-Strings können beliebige Bytes enthalten, aber einige Operationen können den Inhalt verfälschen.

Lösung: Binärdaten als []byte durch die gesamte Pipeline führen. string(decoded) nur aufrufen, wenn der decodierte Inhalt garantiert Text ist.

Before · Go
After · Go
decoded, _ := base64.StdEncoding.DecodeString(pngBase64)
// Binäres PNG als String behandeln führt zu Datenverlust
imageStr := string(decoded)
os.WriteFile("image.png", []byte(imageStr), 0644) // kann korrumpieren
decoded, err := base64.StdEncoding.DecodeString(pngBase64)
if err != nil {
    log.Fatal(err)
}
// Bytes direkt schreiben — keine String-Konvertierung
os.WriteFile("image.png", decoded, 0644)

Methodenvergleich

Alle Varianten sind in der Standardbibliothek enthalten — keine externen Abhängigkeiten für keine dieser Methoden.

Methode
Eingabetyp
Kodierungsvarianten
Streaming
Eigenes Alphabet
Eigenes Padding
Installation nötig
StdEncoding.DecodeString
string
Standard
Nein (stdlib)
URLEncoding.DecodeString
string
URL-sicher
Nein (stdlib)
RawStdEncoding.DecodeString
string
Standard (ohne Padding)
Nein (stdlib)
RawURLEncoding.DecodeString
string
URL-sicher (ohne Padding)
Nein (stdlib)
StdEncoding.Decode
[]byte
Standard
Nein (stdlib)
base64.NewDecoder
io.Reader
Beliebig
Nein (stdlib)
encoding/base64 + NewEncoding
string
Eigenes Alphabet
Nein (stdlib)

Für JWT-Tokens und OAuth-Flows: RawURLEncoding. Für E-Mail-Anhänge und MIME-Daten: StdEncoding. Für große Binärdateien von der Festplatte oder aus dem Netzwerk: einen Reader in base64.NewDecoder einwickeln — der Speicherverbrauch bleibt unabhängig von der Dateigröße konstant. Ein eigenes Alphabet benötigt? base64.NewEncoding(alphabet) erstellt ein neues Kodierungsobjekt für spezielle Anwendungsfälle.

Für schnelle Einmalprüfungen während der Entwicklung ist der Online-Base64-Decoder schneller als das Starten eines Go-Programms.

Häufig gestellte Fragen

Wie decodiere ich einen Base64-String in Go?

encoding/base64 importieren und base64.StdEncoding.DecodeString(s) aufrufen. Die Funktion gibt ([]byte, error) zurück — den Fehler immer prüfen. Enthält der String URL-sichere Zeichen (- und _ statt + und /), stattdessen base64.URLEncoding.DecodeString verwenden. Für JWT-Tokens und die meisten modernen APIs ist RawURLEncoding (ohne Padding) die richtige Wahl.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	encoded := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
	decoded, err := base64.RawURLEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(decoded))
	// {"alg":"HS256","typ":"JWT"}
}

Was ist der Unterschied zwischen StdEncoding und URLEncoding in Go?

StdEncoding verwendet das Standard-Base64-Alphabet mit den Zeichen + und / sowie =-Padding — definiert in RFC 4648 §4. URLEncoding ersetzt + durch - und / durch _, wodurch die Ausgabe in URLs und HTTP-Headern ohne Percent-Encoding sicher verwendbar ist — definiert in RFC 4648 §5. URLEncoding für JWT-Tokens, OAuth-Tokens und alle Daten verwenden, die in Query-Strings eingebettet werden.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// Standard: kann die Zeichen + / und = enthalten
	std := base64.StdEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(std) // "aGVsbG8vd29ybGQ="

	// URL-sicher: ersetzt + durch - und / durch _
	url := base64.URLEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(url) // "aGVsbG8vd29ybGQ=" (gleich — Unterschied zeigt sich bei anderen Bytes)

	// JWT-Header haben nie Padding — RawURLEncoding verwenden
	raw := base64.RawURLEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(raw) // "aGVsbG8vd29ybGQ" (kein abschliessendes =)
}

Wie behebe ich "illegal base64 data"-Fehler in Go?

Dieser Fehler bedeutet, dass die Eingabe Zeichen außerhalb des erwarteten Alphabets enthält oder das Padding falsch ist. Drei häufige Ursachen: StdEncoding auf URL-sichere Eingabe angewendet (auf URLEncoding wechseln), ein Encoder mit Padding auf ungepaddte Eingabe angewendet (auf RawStdEncoding/RawURLEncoding wechseln), oder Leerzeichen/Zeilenumbrüche am Ende. Leerzeichen vor dem Decodieren mit strings.TrimSpace entfernen.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"strings"
)

func main() {
	// Eingabe aus einem Webhook-Payload — Zeilenumbrüche vom Wire-Format bereinigt
	raw := "  aGVsbG8gd29ybGQ=  \n"
	cleaned := strings.TrimSpace(raw)

	decoded, err := base64.StdEncoding.DecodeString(cleaned)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(decoded)) // hello world
}

Wie decodiere ich eine große Base64-kodierte Datei per Streaming in Go?

base64.NewDecoder(base64.StdEncoding, reader) verwenden — dieser umschließt jeden io.Reader und decodiert on-the-fly. Mit io.Copy in das Ziel leiten, ohne die gesamte Datei im Speicher puffern zu müssen. Dies ist das Standardmuster für das Decodieren von Base64-kodierten Binäranhängen oder großen Daten-Payloads.

Go 1.21+
package main

import (
	"encoding/base64"
	"io"
	"log"
	"os"
)

func main() {
	src, err := os.Open("attachment.b64")
	if err != nil {
		log.Fatal(err)
	}
	defer src.Close()

	dst, err := os.Create("attachment.bin")
	if err != nil {
		log.Fatal(err)
	}
	defer dst.Close()

	decoder := base64.NewDecoder(base64.StdEncoding, src)
	io.Copy(dst, decoder)
}

Kann ich einen Base64-JWT-Payload in Go ohne eine JWT-Bibliothek decodieren?

Ja. Ein JWT besteht aus drei Base64url-kodierten Segmenten, die durch Punkte getrennt sind. Den String am "." aufteilen und das zweite Segment (Index 1) mit base64.RawURLEncoding.DecodeString decodieren — JWT-Header und -Payloads verwenden das URL-sichere Alphabet ohne Padding. Das Signatur-Segment (Index 2) ist binär und wird normalerweise nur zur Verifizierung benötigt.

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"strings"
)

func main() {
	token := "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3ItOTAxIiwicm9sZSI6ImFkbWluIn0.SIG"
	parts := strings.Split(token, ".")
	if len(parts) < 2 {
		log.Fatal("invalid JWT format")
	}

	payload, err := base64.RawURLEncoding.DecodeString(parts[1])
	if err != nil {
		log.Fatalf("decode payload: %v", err)
	}
	fmt.Println(string(payload))
	// {"sub":"usr-901","role":"admin"}
}

Welche Kodierung soll ich für Base64-Daten aus einer HTTP-API-Antwort verwenden?

Die API-Dokumentation prüfen oder den kodierten String untersuchen. Enthält er + oder / und endet mit =, StdEncoding verwenden. Enthält er - und _ ohne =, RawURLEncoding verwenden. Im Zweifelsfall zuerst RawURLEncoding probieren — die meisten modernen APIs (OAuth2, JWT, Google Cloud, AWS) verwenden URL-sicheres Base64 ohne Padding.

Go 1.21+
package main

import (
	"encoding/base64"
	"strings"
)

// Kodierungsvariante anhand des kodierten Strings erkennen
func decodeAPIPayload(encoded string) ([]byte, error) {
	// URL-sichere Zeichen ohne Padding — verbreitet in modernen APIs
	if !strings.Contains(encoded, "+") && !strings.Contains(encoded, "/") {
		return base64.RawURLEncoding.DecodeString(encoded)
	}
	// Standard-Base64 mit Padding
	return base64.StdEncoding.DecodeString(encoded)
}

Verwandte Tools

  • Base64 Encoder — Binärdaten oder Text im Browser zu Base64 kodieren, nützlich zum Erstellen von Test-Fixtures zum Einfügen in Go-Unit-Tests.
  • JWT Decoder — alle drei JWT-Segmente auf einmal aufteilen und decodieren, mit feldweiser Payload-Inspektion — kein Go-Code erforderlich, wenn man beim Debuggen nur einen Token lesen möchte.
  • URL Decoder — Percent-kodierte URL-Strings decodieren, praktisch wenn API-Antworten Base64url-Daten mit Percent-kodierten Query-Parametern mischen.
  • JSON Formatter — nach dem Decodieren eines Base64-JWT-Payloads oder einer API-Antwort das JSON hier einfügen, um die Struktur sofort formatiert und validiert anzuzeigen.
Auch verfügbar in:JavaScriptPythonJavaC#
JO
James OkaforSystems Engineer

James is a systems engineer and Go enthusiast who focuses on high-performance microservices, command-line tooling, and infrastructure automation. He enjoys the simplicity and explicitness of Go and writes about building fast, reliable backend systems. When not coding he explores distributed systems concepts and contributes to open-source Go libraries.

HN
Hana NovákováTechnischer Prüfer

Hana is a backend engineer who has built production gRPC and REST services in Go for cloud-native environments. She cares deeply about API correctness, protobuf schema design, and the operational side of running Go services in Kubernetes. She writes about the Go standard library, encoding and marshalling patterns, gRPC best practices, and the subtleties of writing idiomatic Go that is easy to test and maintain.