Každý .NET projekt, na kterém jsem kdy pracoval, dříve nebo později potřebuje dekódovat Base64 — načítání connection stringů z Kubernetes secrets, čtení binárních payloadů z webhooků nebo inspekci JWT tokenů při ladění. Pro dekódování Base64 v C# je primární metodou Convert.FromBase64String(), která vrátí byte[], který pak předáte do Encoding.UTF8.GetString() pro získání čitelného textu. Pro rychlou kontrolu bez psaní kódu zvládne vše Base64 dekodér ToolDeck okamžitě v prohlížeči. Tento průvodce pokrývá Convert.FromBase64String(), span-based TryFromBase64String() pro .NET 5+, vysokovýkonné System.Buffers.Text.Base64 API, extrakci JWT payloadu, dekódování souborů a API odpovědí, streaming přes CryptoStream a čtyři chyby, na které vývojáři C# narážejí nejčastěji.
- ✓Convert.FromBase64String(s) + Encoding.UTF8.GetString(bytes) je standardní dvoustupňový pipeline — funguje ve všech verzích .NET.
- ✓Convert.TryFromBase64String() se vyhýbá výjimkám u neplatného vstupu a zapisuje do Span<byte> — ideální pro horké cesty na .NET 5+.
- ✓System.Buffers.Text.Base64.DecodeFromUtf8() poskytuje dekódování bez alokace pro UTF-8 byte buffery ve výkonnostně kritických službách.
- ✓JWT tokeny používají Base64url (- a _ místo + a /) — vstup musíte normalizovat před voláním Convert.FromBase64String().
- ✓CryptoStream s FromBase64Transform zvládne streamové dekódování velkých souborů bez načítání všeho do paměti.
Co je dekódování Base64?
Base64 kódování převádí binární data do 64znakové ASCII abecedy, aby přežila transport přes textové kanály — JSON pole, HTTP hlavičky, těla e-mailů, XML atributy. Každé 3 bajty vstupu se stanou 4 Base64 znaky, proto je výstup Base64 vždy přibližně o 33 % větší než originál. Dekódování tuto transformaci obrátí. Odsazení = na konci říká dekodéru, kolik bajtů odříznout z poslední skupiny. Jeden = znamená, že poslední blok měl 2 bajty; == znamená 1 bajt. Base64 není šifrování — kdokoli ho může obrátit. Účelem je bezpečný přenos přes kanály, které ničí raw binární data, nikoli důvěrnost.
cmVkaXM6Ly9jYWNoZS1wcm9kLmludGVybmFsOjYzNzkvc2Vzc2lvbi1zdG9yZQ==
redis://cache-prod.internal:6379/session-store
Convert.FromBase64String() — Standardní metoda dekódování
Metoda Convert.FromBase64String() je součástí .NET od dob Framework 1.1. Žádné NuGet balíčky, žádné extra importy nad rámec System — stačí ji zavolat a získáte byte[]. Dvoustupňový pipeline pro dekódování Base64 na C# řetězec je vždy stejný: Convert.FromBase64String() pro získání bajtů, pak Encoding.UTF8.GetString() pro interpretaci těchto bajtů jako text. Háček spočívá v tom, že metoda vrátí raw bajty, ne řetězec. Musíte zvolit správné Encoding pro převod bajtů zpět na text, a volba je důležitější, než většina lidí čeká. Špatné kódování tiše produkuje mojibake — komolené znaky bez jakékoli výjimky.
Minimální funkční příklad
using System; using System.Text; // Connection string uložený jako Base64 v Kubernetes secretu string encoded = "cmVkaXM6Ly9jYWNoZS1wcm9kLmludGVybmFsOjYzNzkvc2Vzc2lvbi1zdG9yZQ=="; byte[] decodedBytes = Convert.FromBase64String(encoded); string connectionString = Encoding.UTF8.GetString(decodedBytes); Console.WriteLine(connectionString); // redis://cache-prod.internal:6379/session-store
Vždy používejte Encoding.UTF8, pokud nemáte konkrétní důvod jinak. Runtime .NET interně reprezentuje řetězce jako UTF-16, ale většina dat procházejících systémovými hranicemi (API odpovědi, konfigurační soubory, secrets) je kódována jako UTF-8. Použití Encoding.ASCII na data s vícebajtovými znaky je tiše nahradí ? — žádná výjimka, jen poškozený výstup.
Ověření round-trip
using System; using System.Text; string original = "postgres://db-admin:Kx8!mQ@db-prod.us-east-1.internal:5432/orders"; // Enkódování string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(original)); Console.WriteLine(encoded); // cG9zdGdyZXM6Ly9kYi1hZG1pbjpLeDghbVFAZGItcHJvZC51cy1lYXN0LTEuaW50ZXJuYWw6NTQzMi9vcmRlcnM= // Dekódování byte[] decoded = Convert.FromBase64String(encoded); string recovered = Encoding.UTF8.GetString(decoded); Console.WriteLine(recovered == original); // True
Volba správného kódování
Encoding předaný do GetString() musí odpovídat tomu, které bylo použito při původním kódování dat. Zvolte špatné a dostanete nesmyslné znaky bez výjimky — dekodér vesele produkuje nesmysly. Zde je praktický přehled:
Encoding.UTF8— bezpečná volba. Zvládne ASCII i celý Unicode. Použijte, pokud nevíte jinak.Encoding.ASCII— pouze pro čistě 7-bitová ASCII data. Vícebajtové znaky se stanou?.Encoding.Unicode— v .NET jde o UTF-16LE. Používají to některé interní řetězce Windows a exporty z PowerShellu.Encoding.Latin1— starší západoevropské kódování. Vyskytuje se ve starých SOAP službách a mainframe integracích.
using System;
using System.Text;
// Stejné bajty, různá kódování — různé výsledky
byte[] decoded = Convert.FromBase64String("w7bDvMOk");
Console.WriteLine(Encoding.UTF8.GetString(decoded)); // öüä (správně)
Console.WriteLine(Encoding.ASCII.GetString(decoded)); // ?????? (ztraceno)
Console.WriteLine(Encoding.Latin1.GetString(decoded)); // öüä (mojibake)Znovupoužitelný pomocný dekodér s ošetřením chyb
Protože Convert.FromBase64String() vyhodí výjimku na špatný vstup a odstraňování mezer se opakuje neustále, držím si v projektech malý helper:
using System;
using System.Text;
static class Base64Helper
{
public static string? DecodeToString(string encoded)
{
if (string.IsNullOrWhiteSpace(encoded))
return null;
// Odstraní mezery, které dekodér .NET odmítá
string cleaned = encoded
.Replace("
", "")
.Replace("
", "")
.Replace(" ", "")
.Trim();
try
{
byte[] bytes = Convert.FromBase64String(cleaned);
return Encoding.UTF8.GetString(bytes);
}
catch (FormatException)
{
return null; // nebo vyhoďte doménově specifickou výjimku
}
}
}
// Použití
string? decoded = Base64Helper.DecodeToString(" cmVkaXM6Ly9jYWNoZQ== \n");
Console.WriteLine(decoded); // redis://cacheConvert.FromBase64String() vyhodí FormatException, pokud vstup obsahuje znaky mimo Base64 abecedu — včetně mezer, konců řádků a URL-safe znaků jako - a _. Výše uvedený helper ošetřuje mezery automaticky.Dekódování Base64 do nestandardních typů
Dekodér vždy vrátí byte[]. Co s těmito bajty uděláte, závisí na původních datech. Někdy jde o GUID uložený jako 16 raw bajtů, někdy o serializovanou protobuf zprávu, někdy o časové razítko v binárním formátu. Zde jsou konverze, které nejčastěji používám.
Base64 na GUID
using System; // Některá API posílají GUIDy jako 22znakový Base64 místo 36znakových hex řetězců string compactGuid = "C0HqetxMckKlZw4CssPUeQ=="; byte[] guidBytes = Convert.FromBase64String(compactGuid); Guid recovered = new Guid(guidBytes); Console.WriteLine(recovered); // 7aea41c0-4cdc-4272-a567-0e02b2c3d479
Base64 na deserializovaný JSON pomocí System.Text.Json
using System;
using System.Text;
using System.Text.Json;
// Base64 zakódovaný JSON payload z fronty zpráv
string encoded = "eyJzZXJ2aWNlIjoicGF5bWVudC1nYXRld2F5IiwicmVnaW9uIjoiZXUtd2VzdC0xIiwicmVwbGljYXMiOjR9";
byte[] jsonBytes = Convert.FromBase64String(encoded);
string json = Encoding.UTF8.GetString(jsonBytes);
Console.WriteLine(json);
// {"service":"payment-gateway","region":"eu-west-1","replicas":4}
// Deserializace do záznamu
var deployEvent = JsonSerializer.Deserialize<DeployEvent>(jsonBytes);
Console.WriteLine($"{deployEvent!.Service} in {deployEvent.Region}");
// payment-gateway in eu-west-1
record DeployEvent(string Service, string Region, int Replicas);Base64 na hex řetězec
using System; // SHA-256 hash uložený jako Base64 string hashBase64 = "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg="; byte[] hashBytes = Convert.FromBase64String(hashBase64); string hex = Convert.ToHexString(hashBytes); Console.WriteLine(hex); // 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08
BinaryFormatter. Má známé zranitelnosti umožňující vzdálené spuštění kódu a je zastaralý v .NET 8+. Pokud kódovaný obsah pochází z externího zdroje, parsujte ho jako JSON nebo protobuf místo použití binární serializace .NET.Přehled metod dekódování Base64
.NET poskytuje více metod dekódování napříč dvěma jmennými prostory. Třída Convert pokrývá dekódování pro obecné účely, zatímco System.Buffers.Text.Base64 cílí na scénáře s vysokou propustností, kde již pracujete s raw UTF-8 byte buffery.
Convert.TryFromBase64String() — Dekódování bez výjimek
Vzor Try je v .NET standardní pro operace, které mohou selhat při vstupu od uživatele. Convert.TryFromBase64String(), dostupný od .NET 5, vrátí bool místo vyhození FormatException. Zapíše dekódované bajty do caller-poskytnutého Span<byte>, takže můžete pro malé payloady použít stack-alokovanou paměť a heap zcela obejít.
using System;
using System.Text;
string userInput = "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=";
// Stack-alokace pro malé payloady (méně než 1 KB je bezpečné pravidlo)
Span<byte> buffer = stackalloc byte[256];
if (Convert.TryFromBase64String(userInput, buffer, out int bytesWritten))
{
string result = Encoding.UTF8.GetString(buffer[..bytesWritten]);
Console.WriteLine(result);
// {"host":"10.0.1.50","port":8443}
}
else
{
Console.WriteLine("Neplatný Base64 vstup — přeskakuji");
}Tento přístup vyniká v request middlewaru nebo validačních pipelinech, kde je špatný vstup očekávaný, ne výjimečný. Vyhazování a chytání FormatException při každém chybném požadavku přidává měřitelnou režii ve velkém měřítku — TryFromBase64String() tomu zcela zabrání.
Validace Base64 vstupu bez dekódování
Běžný vzor v API kontrolerech: zkontrolovat, zda je vstup platný Base64, než ho předáme dál. Jako validátor lze použít TryFromBase64String()s alokací dočasného bufferu:
using System;
static bool IsValidBase64(string input)
{
// Výpočet maximální velikosti dekódovaného výstupu
Span<byte> buffer = stackalloc byte[((input.Length + 3) / 4) * 3];
return Convert.TryFromBase64String(input, buffer, out _);
}
// Použití v API kontroleru
Console.WriteLine(IsValidBase64("eyJob3N0IjoiMTAuMC4xLjUwIn0=")); // True
Console.WriteLine(IsValidBase64("not!!valid!!base64")); // False
Console.WriteLine(IsValidBase64("")); // True (prázdný je platný)TryFromBase64String() vrátí false i při platném vstupu. Pro jistotu vypočítejte požadovanou velikost jako (inputLength / 4) * 3.Dekódování Base64 ze souboru a API odpovědi
Čtení Base64 zakódovaného souboru z disku
Certifikáty, šifrované bloby a soubory datových exportů někdy přicházejí jako Base64 text. Typický postup: přečíst soubor jako řetězec, odstranit mezery nebo konce řádků, které by způsobily FormatException, dekódovat na bajty a zapsat binární výstup. Věnujte pozornost ošetření chyb — chyby I/O a chyby formátu Base64 by měly být zachyceny odděleně.
using System;
using System.IO;
string inputPath = "tls-cert.pem.b64";
string outputPath = "tls-cert.pem";
try
{
string encoded = File.ReadAllText(inputPath).Trim();
// Odstraní konce řádků — dekodér .NET je odmítá
encoded = encoded.Replace("
", "").Replace("
", "");
byte[] decoded = Convert.FromBase64String(encoded);
File.WriteAllBytes(outputPath, decoded);
Console.WriteLine($"Dekódováno {decoded.Length} bajtů -> {outputPath}");
}
catch (IOException ex)
{
Console.Error.WriteLine($"Chyba souboru: {ex.Message}");
}
catch (FormatException ex)
{
Console.Error.WriteLine($"Neplatný Base64: {ex.Message}");
}Dekódování Base64 pole z HTTP API odpovědi
Cloudová API (Azure Key Vault, AWS Secrets Manager, GitHub Contents API) často vracejí binární data jako Base64 řetězce vložené do JSON. Postup je vždy stejný: vykonat HTTP požadavek, parsovat JSON odpověď, extrahovat Base64 pole a dekódovat ho. Příklad níže používá HttpClient a System.Text.Json — obojí je součástí .NET 6+.
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer sk-prod-9f8e7d6c");
try
{
var response = await client.GetAsync("https://api.example.com/secrets/db-password");
response.EnsureSuccessStatusCode();
string body = await response.Content.ReadAsStringAsync();
// API vrátí: {"name":"db-password","value":"cG9zdGdyZXM6eGs5bVAycVI=","version":3}
using var doc = JsonDocument.Parse(body);
string encodedValue = doc.RootElement.GetProperty("value").GetString()!;
byte[] decoded = Convert.FromBase64String(encodedValue);
string secret = Encoding.UTF8.GetString(decoded);
Console.WriteLine($"Secret: {secret}");
// Secret: postgres:xk9mP2qR
}
catch (HttpRequestException ex)
{
Console.Error.WriteLine($"HTTP chyba: {ex.Message}");
}
catch (FormatException ex)
{
Console.Error.WriteLine($"Selhalo dekódování Base64: {ex.Message}");
}catch pro síťové chyby a FormatException. Sloučení dohromady ztěžuje určit, zda API vrátilo špatná data nebo samotný požadavek selhal. V produkci logujte raw hodnotu Base64 (nebo alespoň její délku a prvních 20 znaků) při zachycení FormatException — výrazně to usnadní ladění.Dekódování Base64 z příkazové řádky
Ne vždy potřebujete zkompilovaný projekt. Nástroj dotnet-scripti PowerShell zvládnou dekódování Base64 jednořádkovým příkazem. Pro rychlou inspekci při ladění jsou rychlejší než vytváření konzolové aplikace.
# PowerShell (součást Windows, dostupný na Linux/macOS)
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("eyJob3N0IjoiMTAuMC4xLjUwIn0="))
# {"host":"10.0.1.50"}
# Linux / macOS nativní příkaz base64
echo "eyJob3N0IjoiMTAuMC4xLjUwIn0=" | base64 --decode
# {"host":"10.0.1.50"}
# macOS používá -D místo --decode
echo "eyJob3N0IjoiMTAuMC4xLjUwIn0=" | base64 -D
# dotnet-script (instalace: dotnet tool install -g dotnet-script)
echo 'Console.WriteLine(System.Text.Encoding.UTF8.GetString(Convert.FromBase64String("eyJob3N0IjoiMTAuMC4xLjUwIn0=")));' | dotnet-script eval
# Dekódovat a pretty-print JSON pomocí jq
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode | jq .Pro vkládání zakódovaných řetězců přímo do prohlížeče zvládne Base64 dekodér ToolDeck standardní i URL-safe varianty bez jakéhokoli nastavení.
Vysokovýkonná alternativa: System.Buffers.Text.Base64
Třída System.Buffers.Text.Base64, dostupná od .NET Core 2.1, pracuje na raw UTF-8 byte spanech místo .NET řetězců. Zcela obchází režii konverze řetězec-bajt — žádná mezilehlá alokace řetězce, žádný krok UTF-16 kódování. Sáhnu po ní v ASP.NET Core middlewaru, kde příchozí data jsou jižReadOnlySpan<byte> z těla požadavku. Vytvoření string jen proto, aby ho bylo možné předat do Convert.FromBase64String() zdvojí alokace bez důvodu. V testech BenchmarkDotNet na .NET 8 je span-based cesta přibližně 2-3× rychlejší pro payloady pod 1 KB a rozdíl roste s většími vstupy, protože tlak na GC zůstává plochý.
using System;
using System.Buffers.Text;
using System.Text;
// Simulace raw UTF-8 bajtů z těla HTTP požadavku
byte[] utf8Input = Encoding.UTF8.GetBytes("eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=");
byte[] output = new byte[Base64.GetMaxDecodedFromUtf8Length(utf8Input.Length)];
OperationStatus status = Base64.DecodeFromUtf8(
utf8Input, output, out int bytesConsumed, out int bytesWritten);
if (status == OperationStatus.Done)
{
string result = Encoding.UTF8.GetString(output.AsSpan(0, bytesWritten));
Console.WriteLine(result);
// {"host":"10.0.1.50","port":8443}
Console.WriteLine($"Spotřebováno: {bytesConsumed}, Zapsáno: {bytesWritten}");
// Spotřebováno: 44, Zapsáno: 31
}
else
{
Console.WriteLine($"Dekódování selhalo: {status}");
// Možné: InvalidData, DestinationTooSmall, NeedMoreData
}Návratový typ je OperationStatus — enum se čtyřmi hodnotami: Done, InvalidData, DestinationTooSmalla NeedMoreData. Poslední je užitečný pro částečné dekódování streamovaných dat. Pro absolutně nulovou alokaci spárujte s ArrayPool<byte>.Shared.Rent() místo new byte[].
DecodeFromUtf8InPlace — přepsání vstupního bufferu
using System;
using System.Buffers.Text;
using System.Text;
// Vstupní buffer bude přepsán dekódovanými bajty
byte[] data = Encoding.UTF8.GetBytes("c2VydmVyLWNvbmZpZw==");
OperationStatus status = Base64.DecodeFromUtf8InPlace(data, out int bytesWritten);
if (status == OperationStatus.Done)
{
Console.WriteLine(Encoding.UTF8.GetString(data.AsSpan(0, bytesWritten)));
// server-config
}DecodeFromUtf8InPlace modifikuje vstupní buffer. Nepoužívejte ho, pokud potřebujete původní Base64 řetězec poté — prvních bytesWritten bajtů pole nyní obsahuje dekódovaná data a zbytek je odpad.Na jednu věc je třeba dát pozor: System.Buffers.Text.Base64 nepodporuje URL-safe Base64 přímo. Pokud vstup používá znaky - a _ (JWT tokeny například), stále musíte nahradit je za + a / před voláním těchto metod. Span-based API jsou striktně standardní abecedu RFC 4648. Varianta DecodeFromUtf8Url neexistuje — překvapivá mezera vzhledem k tomu, jak běžný je Base64url v moderních API.
Výstup terminálu se zvýrazněním syntaxe
Knihovna Spectre.Console poskytuje bohatý výstup terminálu včetně zvýraznění JSON — užitečné při budování CLI nástrojů, které dekódují Base64 a zobrazují výsledek. Nainstalujte ji pomocí dotnet add package Spectre.Console.
using System;
using System.Text;
using Spectre.Console;
using Spectre.Console.Json;
string encoded = "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0MywibWF4Q29ubiI6MTAwfQ==";
byte[] decoded = Convert.FromBase64String(encoded);
string json = Encoding.UTF8.GetString(decoded);
// Pretty-print se zvýrazněním syntaxe v terminálu
AnsiConsole.Write(new JsonText(json));
// Vypíše barevný JSON:
// {
// "host": "10.0.1.50",
// "port": 8443,
// "maxConn": 100
// }To je obzvláště praktické pro CLI nástroje, které načítají a dekódují konfiguraci ze vzdálených služeb. Dekódujte Base64 konfiguraci, deserializujte na JSON a vytiskněte zvýrazněný výstup — vše na pár řádků. Spectre.Console má také vykreslování tabulek, progress bary a stromová zobrazení pro případ, že potřebujete v terminálu zobrazit složitější dekódované datové struktury.
Streamové dekódování velkých Base64 souborů pomocí CryptoStream
Načtení 500 MB Base64 souboru pomocí File.ReadAllText() a následné volání Convert.FromBase64String() alokuje přibližně 700 MB haldy: samotný řetězec (UTF-16, tedy dvojnásobek velikosti souboru) plus dekódované pole bajtů. Kombinace CryptoStream + FromBase64Transform dekóduje po blocích, takže spotřeba paměti zůstává konstantní.
using System.IO;
using System.Security.Cryptography;
string inputPath = "database-export.sql.b64";
string outputPath = "database-export.sql";
using var inputStream = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
using var transform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces);
using var base64Stream = new CryptoStream(inputStream, transform, CryptoStreamMode.Read);
using var outputStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write);
base64Stream.CopyTo(outputStream);
Console.WriteLine($"Dekódováno {new FileInfo(outputPath).Length} bajtů -> {outputPath}");Příznak FromBase64TransformMode.IgnoreWhiteSpaces zvládne Base64 s obalováním řádků (PEM soubory, e-mailové exporty) bez ručního čištění. Bez tohoto příznaku způsobí konce řádků ve vstupu FormatException. Jde o nejbližší ekvivalent Javy k getMimeDecoder() v .NET — tiše přeskakuje mezery při dekódování.
Název CryptoStream je zavádějící — Base64 není nic kryptografického. Microsoft umístil FromBase64Transform do jmenného prostoru System.Security.Cryptography, protože implementuje ICryptoTransform, stejné rozhraní jako AES a jiné šifrové transformace. Stream sám jen posílá data přes jakoukoli transformaci po blocích. Považujte ho za obecný pipeline streamové transformace, který se jen ocitl ve špatném jmenném prostoru.
Asynchronní streaming pro scénáře ASP.NET Core
using System.IO;
using System.Security.Cryptography;
async Task DecodeStreamAsync(Stream inputStream, string outputPath)
{
using var transform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces);
using var base64Stream = new CryptoStream(inputStream, transform, CryptoStreamMode.Read);
await using var outputStream = new FileStream(
outputPath, FileMode.Create, FileAccess.Write, FileShare.None,
bufferSize: 81920, useAsync: true);
await base64Stream.CopyToAsync(outputStream);
}
// Použití v endpointu:
// await DecodeStreamAsync(Request.Body, "uploaded-file.bin");CopyTo na CopyToAsync. Synchronní I/O na vlákně požadavku je v Kestrel blokováno a vyhodí InvalidOperationException.Jak dekódovat Base64 JWT token payload v C#
JWT má tři Base64url zakódované segmenty oddělené tečkami. Prostřední segment je payload. Lze ho dekódovat bez JWT knihovny — rozdělte na ., normalizujte Base64url znaky, opravte odsazení a zavolejte Convert.FromBase64String(). Téměř každého to poprvé zaskočí, protože JWT používá - a _ místo + a / a vynechává odsazení =.
using System;
using System.Text;
static string DecodeJwtPayload(string token)
{
string[] parts = token.Split('.');
if (parts.Length != 3)
throw new ArgumentException($"Neplatný JWT: očekávány 3 segmenty, nalezeno {parts.Length}");
// Vezme payload (druhý segment)
string payload = parts[1];
// Nahradí URL-safe znaky standardním Base64
payload = payload.Replace('-', '+').Replace('_', '/');
// Doplní na násobek 4
switch (payload.Length % 4)
{
case 2: payload += "=="; break;
case 3: payload += "="; break;
}
byte[] bytes = Convert.FromBase64String(payload);
return Encoding.UTF8.GetString(bytes);
}
// Test s reálně tvarovaným tokenem
string token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"
+ ".eyJzdWIiOiJ1c3ItNjcyIiwiaXNzIjoiYXV0aC5leGFtcGxlLmNvbSIsImV4cCI6MTc0MTk1NjgwMCwicm9sZXMiOlsiYWRtaW4iLCJiaWxsaW5nIl19"
+ ".SIGNATURE_PLACEHOLDER";
Console.WriteLine(DecodeJwtPayload(token));
// {"sub":"usr-672","iss":"auth.example.com","exp":1741956800,"roles":["admin","billing"]}Krátká poznámka: toto pouze přečte payload. Neověřuje podpis. Pro produkční validaci auth používejte správnou knihovnu jako Microsoft.IdentityModel.JsonWebTokens. Pro ladění, logování a testovací aserce je však tento ruční přístup vše, co potřebujete.
Parsování dekódovaného JWT payloadu do typovaného objektu
Jakmile máte JSON řetězec, deserializujte ho pomocí System.Text.Json pro přístup k jednotlivým claimům bez manipulace s řetězci:
using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
record JwtPayload(
[property: JsonPropertyName("sub")] string Subject,
[property: JsonPropertyName("iss")] string Issuer,
[property: JsonPropertyName("exp")] long Expiration,
[property: JsonPropertyName("roles")] string[] Roles
);
// Po DecodeJwtPayload() z výše
string json = DecodeJwtPayload(token);
var claims = JsonSerializer.Deserialize<JwtPayload>(json)!;
Console.WriteLine($"Uživatel: {claims.Subject}");
Console.WriteLine($"Vydavatel: {claims.Issuer}");
Console.WriteLine($"Vypršení: {DateTimeOffset.FromUnixTimeSeconds(claims.Expiration):u}");
Console.WriteLine($"Role: {string.Join(", ", claims.Roles)}");
// Uživatel: usr-672
// Vydavatel: auth.example.com
// Vypršení: 2025-03-14 12:00:00Z
// Role: admin, billingČasté chyby
Všechny tyto chyby jsem zažil v produkčních C# službách. První dvě jsou zodpovědné za většinu Base64 bugů, které vidím v code review. Každá chyba vypadá v izolaci zřejmě, ale snadno ji přehlédnete, když jste ponořeni do větší funkce a dekódování Base64 je jen jedním krokem pipeline.
Problém: Base64 řetězce načtené z konfiguračních souborů, proměnných prostředí nebo vstupu uživatele mají často trailing newlines. Convert.FromBase64String() odmítne jakýkoli znak mimo Base64 abecedu, včetně \r\n.
Řešení: Zavolejte .Trim() nebo .Replace() pro odstranění mezer před dekódováním.
// Proměnná prostředí má trailing newline
string encoded = Environment.GetEnvironmentVariable("DB_PASS_B64")!;
byte[] decoded = Convert.FromBase64String(encoded);
// FormatException: The input is not a valid Base-64 stringstring encoded = Environment.GetEnvironmentVariable("DB_PASS_B64")!;
string cleaned = encoded.Replace("\n", "").Replace("\r", "").Trim();
byte[] decoded = Convert.FromBase64String(cleaned);
Console.WriteLine(Encoding.UTF8.GetString(decoded));Problém: JWT tokeny a některé API payloady používají - a _ (URL-safe abeceda). Standardní dekodér akceptuje pouze + a / — vyhodí FormatException na prvním znaku -.
Řešení: Nahraďte - za + a _ za / před dekódováním. Opravte také odsazení.
// JWT payload — používá URL-safe Base64 string payload = "eyJzdWIiOiJ1c3ItNjcyIn0"; byte[] decoded = Convert.FromBase64String(payload); // FormatException
string payload = "eyJzdWIiOiJ1c3ItNjcyIn0";
payload = payload.Replace('-', '+').Replace('_', '/');
switch (payload.Length % 4)
{
case 2: payload += "=="; break;
case 3: payload += "="; break;
}
byte[] decoded = Convert.FromBase64String(payload);
Console.WriteLine(Encoding.UTF8.GetString(decoded));
// {"sub":"usr-672"}Problém: Volání Encoding.UTF8.GetString() na dekódovaných bajtech obrázku nebo protobufu produkuje nesmysly. Navíc zpětný převod tohoto řetězce na bajty tiše poškodí data, protože neplatné UTF-8 sekvence jsou nahrazeny.
Řešení: Udržujte binární data jako byte[] v celém pipeline. Volejte GetString() pouze tehdy, když víte, že obsah je text.
byte[] decoded = Convert.FromBase64String(pngBase64);
string imageStr = Encoding.UTF8.GetString(decoded); // poškodí binární data
File.WriteAllText("image.png", imageStr); // poškozený souborbyte[] decoded = Convert.FromBase64String(pngBase64);
// Zapisujte bajty přímo — žádná konverze na řetězec
File.WriteAllBytes("image.png", decoded);Problém: Některá starší .NET Framework API výchozí na aktuální ANSI kódovou stránku systému, která se liší mezi stroji. Windows server s kódovou stránkou 1252 a Linux kontejner s UTF-8 produkují různé řetězce ze stejných bajtů.
Řešení: Vždy explicitně uveďte Encoding.UTF8. Nikdy se nespoléhejte na výchozí platformu.
byte[] decoded = Convert.FromBase64String(encoded); // Encoding.Default se liší mezi platformami string result = Encoding.Default.GetString(decoded);
byte[] decoded = Convert.FromBase64String(encoded); string result = Encoding.UTF8.GetString(decoded); // konzistentní na Windows, Linux, macOS
Porovnání metod
.NET nabízí více metod dekódování Base64, než si většina vývojářů uvědomuje. Tabulka níže pokrývá každou vestavěnou možnost plus dvě nejčastější alternativy třetích stran. Sloupec "Alokace" je nejdůležitější ve službách s vysokou propustností — metoda, která alokuje nové byte[] při každém volání, zvyšuje tlak na GC v těsných smyčkách.
Pro každodenní práci: Convert.FromBase64String(). Pro horké cesty, kde validujete vstup uživatele: TryFromBase64String(). Pro ASP.NET Core middleware pracující na raw bajtech požadavku: Base64.DecodeFromUtf8(). Pro velké soubory: CryptoStream + FromBase64Transform. BouncyCastle má smysl pouze tehdy, pokud je již ve vašem dependency tree pro jiné kryptografické operace.
Pro rychlé ověření bez kompilování čehokoli je online Base64 dekodér rychlejší než psaní jednorázové konzolové aplikace.
Často kladené otázky
Jak dekódovat Base64 řetězec na text v C#?
Zavolejte Convert.FromBase64String() pro získání pole bajtů, pak ho předejte do Encoding.UTF8.GetString(). Kódování musí odpovídat tomu, které bylo použito při enkódování — UTF-8 je bezpečná volba pro téměř všechny moderní systémy. Pokud vstup může obsahovat mezery nebo konce řádků, zavolejte .Trim() nebo je odstraňte před dekódováním.
using System; using System.Text; string encoded = "cG9zdGdyZXM6eGs5bVAycVI="; byte[] bytes = Convert.FromBase64String(encoded); string result = Encoding.UTF8.GetString(bytes); Console.WriteLine(result); // postgres:xk9mP2qR
Jaký je rozdíl mezi Convert.FromBase64String() a Convert.TryFromBase64String()?
FromBase64String() vyhodí FormatException při neplatném vstupu. TryFromBase64String() vrátí bool a zapíše výsledek do caller-poskytnutého Span<byte>, takže je vhodný pro kritické cesty, kde chcete vyhnout se režii výjimek. TryFromBase64String() vyžaduje .NET 5 nebo novější.
using System;
string input = "maybe-not-valid-base64!!";
Span<byte> buffer = stackalloc byte[256];
if (Convert.TryFromBase64String(input, buffer, out int written))
Console.WriteLine($"Dekódováno {written} bajtů");
else
Console.WriteLine("Neplatný Base64 vstup");Jak dekódovat Base64url payload JWT tokenu v C#?
Rozdělte token na tečkách, vezměte druhý segment, nahraďte - za + a _ za /, doplňte na násobek 4 pomocí =, pak zavolejte Convert.FromBase64String(). JWT tokeny používají URL-safe Base64 abecedu, kterou standardní dekodér .NET nepodporuje přímo.
string token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3ItNjcyIn0.SIG";
string payload = token.Split('.')[1];
payload = payload.Replace('-', '+').Replace('_', '/');
switch (payload.Length % 4)
{
case 2: payload += "=="; break;
case 3: payload += "="; break;
}
byte[] bytes = Convert.FromBase64String(payload);
Console.WriteLine(Encoding.UTF8.GetString(bytes));
// {"sub":"usr-672"}Jak zvolit správné kódování při dekódování Base64 v C#?
Použijte Encoding.UTF8 jako výchozí — zvládne ASCII i vícebajtové znaky Unicode. Encoding.ASCII použijte pouze pokud máte jistotu, že data jsou čistě 7-bitové ASCII. Encoding.Unicode (v .NET jde o UTF-16LE) použijte jen tehdy, když byla původní data kódována jako UTF-16, což se občas stává u interních řetězců Windows a exportů z PowerShellu.
Proč Convert.FromBase64String() vyhodí FormatException?
Tři časté příčiny: vstup obsahuje mezery nebo konce řádků (odstraňte je před dekódováním), vstup používá URL-safe znaky jako - a _ (nahraďte je za + a / v daném pořadí), nebo chybí či je nesprávné odsazení (celková délka musí být násobek 4 po doplnění). Na rozdíl od Javy .NET nemá vestavěný MIME dekodér, který toleruje mezery — vstup musíte vyčistit sami nebo použít CryptoStream s FromBase64Transform v režimu IgnoreWhiteSpaces.
// Oprava mezer
string cleaned = rawInput.Replace("\n", "").Replace("\r", "").Trim();
byte[] decoded = Convert.FromBase64String(cleaned);Mohu streamovat dekódování velkých Base64 dat v C#?
Ano. Použijte CryptoStream s FromBase64Transform ze System.Security.Cryptography. To dekóduje po blocích při čtení, takže spotřeba paměti zůstává konstantní bez ohledu na velikost souboru. Předejte FromBase64TransformMode.IgnoreWhiteSpaces, pokud vstup obsahuje konce řádků. Na .NET 6+ můžete také použít vzor IAsyncEnumerable s Base64.DecodeFromUtf8() pro ruční blokové zpracování, přestože CryptoStream je jednodušší pro dekódování soubor-soubor.
using System.IO;
using System.Security.Cryptography;
using var input = File.OpenRead("payload.b64");
using var transform = new FromBase64Transform();
using var cryptoStream = new CryptoStream(input, transform, CryptoStreamMode.Read);
using var output = File.Create("payload.bin");
cryptoStream.CopyTo(output);Související nástroje
- Base64 Encoder — zakóduje text nebo binární data do Base64 v prohlížeči, užitečné pro generování testovacích dat k vložení do C# unit testů.
- JWT Decoder — dekóduje a zobrazí všechny tři segmenty JWT najednou s inspekcí jednotlivých polí payloadu — rychlejší než psaní C# helperu, když potřebujete jen přečíst token.
- URL Decoder — percent-dekóduje URL-zakódované řetězce, užitečné když API odpovědi kombinují Base64url data s percent-zakódovanými query parametry.
- JSON Formatter — po dekódování Base64 JWT payloadu nebo API konfigurace sem vložte JSON pro pretty-print a validaci struktury.