Datei hochladen
  1. base64hub
  2. Base64 im Code
  3. C#
Code

Base64 in C#

System.Convert beherrscht Base64 seit .NET Framework 1.0, und .NET 9 hat System.Buffers.Text.Base64Url für URL-sichere Strings hinzugefügt. Die Ausgaben unten stammen von .NET 9.

Einen String kodieren und dekodieren

Convert arbeitet mit Bytes, wählen Sie also ausdrücklich eine Kodierung. Für alles, was Ihren Prozess verlässt, ist das fast immer UTF-8:

using System.Text;

string enc = Convert.ToBase64String(Encoding.UTF8.GetBytes("héllo wörld"));
Console.WriteLine(enc);   // aMOpbGxvIHfDtnJsZA==

string dec = Encoding.UTF8.GetString(Convert.FromBase64String(enc));
Console.WriteLine(dec);   // héllo wörld

Encoding.Unicode ist UTF-16LE und verdoppelt die Größe von ASCII-Text. Richtig ist es nur, wenn die Gegenseite UTF-16 erwartet, zum Beispiel beim Format für kodierte PowerShell-Befehle.

Ein häufiger Praxisfall ist der HTTP-Basic-Auth-Header:

string token = Convert.ToBase64String(Encoding.UTF8.GetBytes("user:pass"));
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", token);
// Authorization: Basic dXNlcjpwYXNz

Der Basic-Auth-Header-Generator erzeugt denselben Wert im Browser.

URL-sicheres Base64: Base64Url in .NET 9

.NET 9 hat System.Buffers.Text.Base64Url eingeführt. Es kodiert ohne Padding und dekodiert mit oder ohne:

using System.Buffers.Text;

byte[] d = Encoding.UTF8.GetBytes("<<???>>");
Console.WriteLine(Base64Url.EncodeToString(d));            // PDw_Pz8-Pg

byte[] a = Base64Url.DecodeFromChars("PDw_Pz8-Pg");        // <<???>>
byte[] b = Base64Url.DecodeFromChars("PDw_Pz8-Pg==");      // <<???>>

Das Standardalphabet lehnt es ab: Base64Url.DecodeFromChars("PDw/Pz8+Pg") wirft eine FormatException. Daneben gibt es Span-basierte Überladungen (EncodeToChars, DecodeFromUtf8, TryDecodeFromChars), die Allokationen vermeiden.

Auf älteren Runtimes ohne das Paket Microsoft.Bcl.Memory wandeln Sie von Hand um:

string url = Convert.ToBase64String(d)
    .TrimEnd('=').Replace('+', '-').Replace('/', '_');    // PDw_Pz8-Pg

Zum Dekodieren brauchen Sie die umgekehrten Ersetzungen plus Padding auf ein Vielfaches von 4:

static byte[] FromBase64Url(string s)
{
    s = s.Replace('-', '+').Replace('_', '/');
    s = s.PadRight(s.Length + (4 - s.Length % 4) % 4, '=');
    return Convert.FromBase64String(s);
}

Encoding.UTF8.GetString(FromBase64Url("PDw_Pz8-Pg"));   // <<???>>

ASP.NET-Core-Projekte können stattdessen WebEncoders.Base64UrlEncode aus Microsoft.AspNetCore.WebUtilities verwenden. Mehr zu den beiden Alphabeten unter Base64 vs. Base64URL.

Eingaben ohne Exceptions prüfen

Convert.FromBase64String wirft bei ungültiger Eingabe eine System.FormatException. Unter .NET 9 ist die Meldung in fast allen Fällen dieselbe:

The input is not a valid Base-64 string as it contains a non-base 64 character,
more than two padding characters, or an illegal character among the padding characters.

Diese Meldung erhielten wir für PDw_Pz8-Pg== (URL-sicher), aGk=!! (Fremdzeichen), aGk (ohne Padding), a und aGk==. Leerraum wird akzeptiert (" aGk= " und "aGVs\nbG8K" lassen sich problemlos dekodieren), ebenso Padding-Bits ungleich null (aGl=).

Um Exceptions in Hot Paths zu vermeiden, verwenden Sie die Try-Variante mit einem Puffer oder Base64.IsValid (.NET 8+):

Span<byte> buf = stackalloc byte[16];
Convert.TryFromBase64String("aGk=", buf, out int n);   // True, n = 2
Convert.TryFromBase64String("aGk", buf, out n);        // False, n = 0

System.Buffers.Text.Base64.IsValid("aGk=");      // True
System.Buffers.Text.Base64.IsValid("aGk");       // False
Base64Url.IsValid("PDw_Pz8-Pg");                 // True

Der Puffer muss groß genug für die dekodierte Ausgabe sein, sonst gibt TryFromBase64String selbst bei gültiger Eingabe false zurück. Bemessen Sie ihn mit (s.Length * 3) / 4. Bei Strings, die scheitern, helfen der Base64-Validator und die Anleitung zu Base64-Fehlern.

Zeilenumbrüche (MIME)

Base64FormattingOptions.InsertLineBreaks bricht die Ausgabe nach 76 Zeichen mit \r\n um, ohne abschließenden Zeilenumbruch:

string mime = Convert.ToBase64String(
    Encoding.ASCII.GetBytes(new string('x', 60)),
    Base64FormattingOptions.InsertLineBreaks);
// "eHh4eHh4...eHh4" (76 chars) + "\r\n" + "eHh4"

FromBase64String nimmt die umgebrochene Form unverändert zurück. Der MIME-Base64-Encoder erzeugt dasselbe Layout.

Eine Datei kodieren und dekodieren

Console.WriteLine(Convert.ToBase64String(File.ReadAllBytes("hello.txt")));  // aGVsbG8K
File.WriteAllBytes("copy.txt", Convert.FromBase64String("aGVsbG8K"));

Große Dateien mit CryptoStream

ToBase64Transform und FromBase64Transform lassen sich in einen CryptoStream stecken, der den Speicherverbrauch konstant hält. Trotz des Namespace ist keine Kryptografie im Spiel:

using System.Security.Cryptography;

using (var input = File.OpenRead("big.bin"))
using (var output = File.Create("big.b64"))
using (var b64 = new CryptoStream(output, new ToBase64Transform(), CryptoStreamMode.Write))
{
    input.CopyTo(b64);
}

using (var input = new CryptoStream(File.OpenRead("big.b64"),
                                    new FromBase64Transform(), CryptoStreamMode.Read))
using (var output = File.Create("big.out"))
{
    input.CopyTo(output);
}

Erst das Dispose des CryptoStream schreibt den letzten Block samt Padding; fehlt es, ist die Ausgabe abgeschnitten. Bei einer 300-KB-Testdatei stimmten beide Richtungen mit dem Ergebnis im Speicher überein. Für eine schnelle Kontrolle von Hand öffnen Sie das Ergebnis mit Base64 in Datei.

Häufige Fallstricke

  • Data-URI-Präfixe. data:image/png;base64, enthält : und ;, die eine FormatException auslösen. Entfernen Sie alles bis einschließlich Komma.
  • URL-sichere Tokens in Convert. JWT-Teile scheitern mit der allgemeinen Meldung oben. Verwenden Sie Base64Url oder den JWT-Decoder.
  • Encoding.Default. Unter .NET Framework ist das die ANSI-Codepage, unter .NET Core und neuer UTF-8. Code, der zwischen beiden wandert, ändert die Ausgabe für Nicht-ASCII-Text.
  • Base64 ist keine Verschlüsselung. Mit Base64 „geschützte“ Connection-Strings sind für jeden Klartext. Siehe Kodierung vs. Verschlüsselung.

Versionshinweise

  • .NET Framework 1.0+: Convert.ToBase64String, FromBase64String, ToBase64Transform.
  • .NET Core 2.1+: Span-Überladungen Convert.TryFromBase64String, TryToBase64Chars und die UTF-8-Klasse System.Buffers.Text.Base64.
  • .NET 8: Base64.IsValid.
  • .NET 9: Base64Url, für ältere Zielplattformen auch über Microsoft.Bcl.Memory verfügbar.

Häufige Fragen

Wie behebe ich „The input is not a valid Base-64 string“?

Suchen Sie nach URL-sicheren Zeichen (-, _), fehlendem Padding und Data-URI-Präfixen. Convert.FromBase64String akzeptiert nur das Standardalphabet mit korrektem Padding. Für Tokens verwenden Sie unter .NET 9 Base64Url.DecodeFromChars, das Eingaben mit und ohne Padding annimmt.

Kann ich Base64Url unter .NET 8 oder .NET Framework nutzen?

Base64Url ist ab .NET 9 eingebaut. Für ältere Zielplattformen liefert Microsoft denselben Typ im Paket Microsoft.Bcl.Memory. Ohne das Paket wandeln Sie die Standardausgabe mit TrimEnd('=') und zwei Replace-Aufrufen um.

Warum ist Encoding.Unicode für Base64 von Text falsch?

Encoding.Unicode ist UTF-16LE, aus hi wird also aABpAA== statt aGk=. Verwenden Sie Encoding.UTF8, sofern der Empfänger nicht UTF-16 erwartet, wie es -EncodedCommand von PowerShell tut.

Weiterlesen