Skip to content

Guide

Base64 spiegato: perché, quando e le varianti comuni

Un alfabeto di 64 caratteri, una penalità del 33% in dimensioni e tre varianti quasi identiche finché non si rompono a vicenda.

By Published

Base64 è ovunque — allegati email, token JWT, URI dati, blocchi PEM dei certificati, segreti client OAuth, payload delle notifiche push — e quasi nessuno si ferma a chiedersi cosa stia effettivamente facendo. Svolge un lavoro specifico, ha tre varianti quasi identiche, e le differenze tra di esse causano la maggior parte dei bug.

Quale problema risolve Base64

Molti canali di trasporto sono progettati per il testo, non per byte arbitrari. I corpi delle email storicamente dovevano essere ASCII stampabile. Gli URL non possono contenere caratteri di controllo grezzi o spazi. Le stringhe JSON devono essere Unicode valido. Se vuoi inviare un PNG all’interno di uno qualsiasi di questi, i byte grezzi romperanno il canale.

Base64 prende qualsiasi sequenza di byte e la ri-esprime usando solo 64 caratteri sicuri più un padding opzionale. Il risultato si adatta ovunque si adatti il testo, e un decoder recupera i byte originali esattamente. Non c’è perdita, nessuna compressione e nessuna sicurezza — solo un cambio di formato.

L’alfabeto

Il Base64 standard (RFC 4648 §4) usa 65 caratteri in totale:

  • A–Z — valori 0–25
  • a–z — valori 26–51
  • 0–9 — valori 52–61
  • + — valore 62
  • / — valore 63
  • = — padding, nessun valore

Ogni carattere trasporta 6 bit (perché 26 = 64). Tre byte di input (24 bit) mappano su quattro caratteri di output (24 bit). Quando l’input non è un multiplo di 3 byte, il codificatore aggiunge zero a destra ed emette =per ogni passo di padding. Un byte rimanente diventa “due caratteri + ==”; due byte rimanenti diventano “tre caratteri + =”.

Perché l’output è più grande del 33%

4 caratteri di output trasportano solo quello che trasportavano 3 byte di input, quindi l’inflazione è esattamente 4/3 = 1,333…, ovvero il 33,3% in più. Il padding aggiunge un po’ di più per gli input brevi. Un file binario di 1 MB diventa una stringa Base64 di 1,33 MB. Questo è il compromesso per il trasporto sicuro nel testo; se non puoi permettertelo, non puoi usare Base64.

Prova il nostro codificatore / decodificatore Base64 con un input di esempio — vedrai il rapporto di dimensioni riportato accanto al risultato.

Le tre varianti che incontrerai

Base64 standard (RFC 4648 §4)

L’originale. L’alfabeto include + e /, padding con =richiesto. Usato dai file PEM (certificati TLS, chiavi SSH), XML Signature, allegati SOAP e l’intestazione HTTP Authorization: Basic.

Base64url (RFC 4648 §5)

Sicuro per URL e nomi di file. Sostituisce + con - e / con _. Il padding è tecnicamente opzionale nella specifica ma quasi sempre omesso in pratica. Questo è ciò che usano JWT, JWS, JWE, OAuth PKCE, WebPush VAPID e WebAuthn. I due caratteri che differiscono sono quelli che in precedenza richiedevano percent-encoding negli URL (%2B per + e %2F per /), e il padding mancante aggira anche %3D.

Base64 standard e URL-safe non sono direttamente intercambiabili. Un decoder che conosce un alfabeto rifiuterà l’input nell’altro. Se stai collegando dati tra un flusso OAuth e uno strumento che si aspetta Base64 in stile PEM, transcodifica al confine. Vedi il nostro confronto Base64 vs Base64url per le regole esatte.

MIME Base64 (RFC 2045)

La variante originale degli allegati email. Stesso alfabeto del Base64 standard, ma con un’interruzione di riga fissa (\r\n) inserita ogni 76 caratteri perché i vecchi relay SMTP si bloccavano su righe lunghe. Lo spazio bianco all’interno di MIME Base64 deve essere ignorato dal decoder. La maggior parte dei decoder moderni accetta silenziosamente gli spazi bianchi in qualsiasi input Base64, ma un decoder RFC 4648 rigoroso è autorizzato a rifiutarlo. Se stai generando Base64 per un campo JSON o un JWT, non inserire mai interruzioni di riga.

Dove Base64 appare nel mondo reale

  • Token JWT — tre sezioni base64url (senza padding) unite da punti. Header. Payload. Firma.
  • HTTP Basic auth username:passwordcodificato in Base64 standard, inviato nell’intestazione Authorization. (Perché “Basic” non è un meccanismo di sicurezza senza TLS.)
  • URI dati data:image/png;base64,iVBORw0KG… incorpora il binario direttamente in HTML o CSS. La parte image/png è un tipo MIME — senza di essa il browser deve sniffare i byte e potrebbe rifiutare di renderizzare.
  • File PEM — certificati TLS, chiavi SSH, messaggi PGP. Base64 standard avvolto in intestazioni -----BEGIN…----- / -----END…-----.
  • Allegati email — MIME Base64 con interruzione di riga ogni 76 caratteri.
  • Risorse Kubernetes Secret — valori codificati in Base64 standard (il che confonde notoriamente le persone facendole pensare che siano cifrati).

Insidie comuni

Codificare stringhe senza specificare UTF-8

Base64 non sa nulla dei caratteri — codifica byte. Se codifichi in Base64 la stringa “café”, il risultato dipende interamente dalla codifica byte che hai scelto (UTF-8 dà 5 byte producendo Y2Fmw6k=; Latin-1 dà 4 byte producendo Y2Fm6Q==). Decodificare con un’assunzione diversa produce spazzatura. La convenzione moderna è byte UTF-8 per qualsiasi input di testo.

Mescolare standard e URL-safe

Una stringa contenente - o _ è base64url; i decoder Base64-standard la rifiutano. Una stringa contenente + o / è standard; i decoder URL-safe la rifiutano. Se controlli entrambe le estremità, scegli uno e documentalo. Se non lo fai, normalizza in input per sostituzione di classe di caratteri prima di decodificare.

Mancata corrispondenza del padding

I JWT e formati simili eliminano il padding. I decoder ingenui richiedono il padding e lanciano InvalidBase64. La correzione è riaggiungere caratteri =fino a quando la lunghezza dell’input è un multiplo di 4 — di solito uno o due di essi.

Trattare Base64 come confine di sicurezza

I Secret di Kubernetes sono Base64, non cifrati. Mettere in Base64 una password nel codice client non la protegge. Base64 non nasconde nulla a chiunque abbia un decoder — e ogni laptop ne ha uno.

Gonfiore degli URI dati

Incorporare un’immagine da 200 KB con Base64 la porta a 266 KB e blocca il thread principale mentre il browser analizza l’URI. Per qualcosa oltre qualche KB, servi il file da un normale URL e lascia che il browser lo memorizzi nella cache.

Prova il codificatore

Incolla qualsiasi testo o carica un file nel nostro codificatore / decodificatore Base64. Supporta sia gli alfabeti standard che URL-safe, mostra il comportamento del padding esplicitamente e riporta le dimensioni dei byte di input/output in modo da poter vedere l’inflazione per il tuo input specifico. La voce del glossario Base64è la versione in un paragrafo.

Conclusione

Base64 è una comodità di trasporto, non una funzionalità di sicurezza. Ti costa un terzo dei byte e ti ripaga in compatibilità con i canali solo testo. Le varianti contano — standard per PEM e HTTP Basic, URL-safe per JWT e OAuth, MIME per le email — e non si decodificano a vicenda senza transcodifica. Sii sempre esplicito su quale variante produci e consumi, e codifica sempre le stringhe Unicode in byte UTF-8 prima.

Frequently asked questions

Base64 è una cifratura?
No. Base64 è codifica, non cifratura — non c'è chiave, e chiunque può invertirlo istantaneamente. Esiste per rendere i dati binari sicuramente trasportabili attraverso canali solo testo (corpi email, JSON, URL). Trattare Base64 come misura di sicurezza è una vulnerabilità, non una difesa.
Perché l'output codificato è sempre più lungo dell'input?
Ogni carattere Base64 trasporta solo 6 bit di informazioni; un byte di input ne trasporta 8. Quindi ogni 3 byte di input diventano 4 caratteri di output — un'inflazione del 4/3 (≈33%). Con il padding, gli input molto brevi vengono arrotondati al prossimo multiplo di 4, aggiungendo alcuni byte in più.
Qual è la differenza tra Base64 e Base64url?
Due caratteri nell'alfabeto. Il Base64 standard usa '+' e '/' per gli ultimi due dei 64 simboli, più '=' per il padding. Base64url sostituisce '+' con '-' e '/' con '_' in modo che l'output sia sicuro da inserire negli URL e nei nomi di file senza ulteriori escape. I JWT omettono inoltre il padding '='. Le due varianti non sono direttamente intercambiabili; è necessario transcodificare al confine.
Perché il padding (=) a volte appare e a volte no?
Il padding rende la lunghezza dell'output un multiplo di 4 — richiesto da alcuni decoder rigorosi (vecchi gateway email, certi certificati TLS). Gli standard web moderni (JWT, PKCE di OAuth, WebPush) eliminano il padding perché la lunghezza può sempre essere inferita. Se stai passando una stringa a un decoder sconosciuto, includi il padding; se produci JWT o qualcosa che corrisponde a RFC 4648 §5, omettilo.
Base64 può gestire stringhe Unicode direttamente?
No — Base64 codifica byte, non caratteri. Per codificare in Base64 una stringa Unicode, prima la codifichi in byte (UTF-8 è la scelta universale), poi quei byte in Base64. Dimenticare questo passaggio è la fonte di ogni bug 'mojibake' nel codice di gestione Base64.
Gli URI dati (data:image/png;base64,...) sono il modo giusto per incorporare immagini?
Per piccole icone e SVG inline, sì — risparmiano un round trip HTTP. Per qualcosa di più grande di qualche KB, no — l'inflazione del 33% costa più di una richiesta separata, i dati non possono essere memorizzati nella cache indipendentemente, e i browser analizzano gli URI dati sul thread principale, bloccando il rendering.

Related

Published May 31, 2026