Strumenti per sviluppatori · Codificatore e decodificatore Base64
Base64 vs base64url: perché un decoder standard rifiuta - e _
· Come funziona
base64 codifica flusso di lavoro dello sviluppatore
base64url scambia + e / con - e _ in modo che l'output possa viaggiare negli URL e nei nomi dei file senza scappare. Questo post spiega i due alfabeti, come convertirli tra loro e perché di solito viene eliminato anche il riempimento.
Il token che decodifica ovunque tranne il tuo codice: un errore di carattere non valido causato da un singolo - o _
Un segmento JWT non riesce a decodificare nel decoder Base64 standard con un trattino di denominazione di errore di carattere non valido. Ma visivamente non appare alcun trattino. Guarda ancora: lo fa. La versione base64url utilizza - dove Base64 standard utilizza + e _ dove utilizza /. Molti decoder accettano solo un alfabeto e il token codificato per la sicurezza URL verrà rifiutato dal codice che prevede RFC 4648 Base64 standard.
I due alfabeti sono equivalenti; la conversione tra di loro è una sostituzione meccanica dei caratteri. Il problema sorge perché + e / hanno significati negli URL. Un segno più rappresenta lo spazio nei dati del modulo application/x-www-form-urlencoded. La barra è il separatore del percorso in URL. Se incorpori Base64 direttamente nel parametro di query URL senza codifica percentuale + e il decoder /, potrebbe interpretarli erroneamente.
Perché + e / sono un problema negli URL e nei nomi dei file: il significato riservato di / nei percorsi e di + come spazio nei dati del modulo
A + potrebbe essere letto come spazio prima di raggiungere il decodificatore. A / potrebbe dividere il valore del parametro nel posto sbagliato. RFC La sezione 4648 5 definisce l'alfabeto base64url per eliminare l'ambiguità: usa - invece di + e _ invece di /, in modo che l'output sia sicuro negli URL e nei nomi dei file. I due alfabeti sono identici tranne due caratteri.
Base64 standard utilizza i caratteri nelle posizioni 62 e 63: A–Z (0–25), a–z (26–51), 0–9 (52–61), + (62), / (63). base64url utilizza A–Z (0–25), a–z (26–51), 0–9 (52–61), - (62), _ (63). Tutto il resto (raggruppamento dei bit, regole di riempimento, mappatura dei bit sugli indici) è lo stesso. La stringa di indici per Base64 standard produrrà una stringa di indici per base64url; solo il carattere nelle posizioni 62 e 63 sarà diverso.
L'alfabeto base64url dalla sezione RFC 4648 5 — i due caratteri sostituiti e perché non cambia nient'altro
Se l'input non contiene indici 62 o 63 (no + o / in standard, no - o _ in base64url), entrambi gli alfabeti producono un output identico. La conversione da Base64 standard a base64url è semplice da trovare e sostituire: scambia + per - e / per _. La decodifica della stringa base64url in Base64 standard richiede il contrario: scambia - per + e _ per /.
La conversione è simmetrica e sempre valida. Se riscontri un token che non riesce a decodificare con un nome di errore di carattere non valido - o _, controlla se il decodificatore accetta base64url. In caso contrario, applicare la sostituzione dei caratteri e, se l'input è altrimenti ben formato, la decodifica dovrebbe riuscire. Considera l'intestazione JWT {"alg":"HS256","typ":"JWT"} codificata come base64url. I byte standard UTF-8 passano attraverso il raggruppamento di bit: tre byte diventano quattro indici, cercati nell'alfabeto base64url. ToolAcre espone il riempimento come scelta del codificatore anziché legarlo all'attivazione/disattivazione dell'alfabeto. Questa separazione è una prova utile: l'output di URL-safe può essere riempito o non riempito, mentre il decodificatore normalizza entrambe le forme prima di chiamare la primitiva del browser. Alfabeto e riempimento sono convenzioni correlate, non un interruttore.
Il riempimento in base64url è facoltativo per convenzione: perché i JWT omettono = e come un decodificatore può ripristinarlo dalla lunghezza
Quando l'indice è 62, il carattere di output è -; quando 63, l'output è _. Byte identici tramite l'alfabeto standard produrrebbero + all'indice 62 e / all'indice 63. La conversione del risultato base64url in standard è un'operazione carattere per carattere: cerca - e sostituisci con +, cerca _ e sostituisci con /, quindi decodifica come al solito.
I byte recuperati sono identici perché gli indici erano identici; differiscono solo i simboli. Il riempimento in base64url è facoltativo per convenzione, anche se lo standard lo consente. I JWT sono strutturati come tre segmenti base64url uniti da punti; ogni segmento utilizza il riempimento se richiesto, ma molte implementazioni lo omettono e si basano sul fatto che l'applicazione che lo utilizza conosce la lunghezza in byte prevista.
Esempio realizzato: conversione di un segmento di intestazione JWT in Base64 standard: sostituzione di caratteri, aggiunta di riempimento, decodifica in JSON
Un decodificatore può ripristinare il riempimento mancante dividendo la lunghezza della stringa per quattro, calcolando il resto, aggiungendo 0, 1 o 2 segni di uguale. Se la lunghezza della stringa non è multipla di quattro, è evidente la mancanza di riempimento. Se la lunghezza è multipla di quattro, la stringa è stata riempita e poi rimossa, oppure l'input è già multiplo di quattro byte (terminando con tre byte nel blocco finale, senza bisogno di riempimento).
La concatenazione di segmenti base64url richiede attenzione al riempimento. Se tre segmenti terminano ciascuno con =, la concatenazione produce direttamente stringhe come AAAA=BBBB=CCCC=, dove il riempimento al centro ora è costituito da caratteri vaganti, non da indicatori di terminazione. Questo è il motivo per cui i JWT omettono il riempimento in ogni segmento: la struttura a tre segmenti è esplicita, quindi la decodifica procede in modo indipendente su ciascuna parte e il riempimento all'interno della stringa concatenata non è necessario e interromperebbe l'analisi.
Errori comuni: mescolare gli alfabeti in una stringa o lo standard Base64 con codifica percentuale invece di utilizzare base64url
Se crei un payload multisegmento, decidi la convenzione di riempimento all'inizio: includi in ogni segmento e non concatena mai direttamente, oppure ometti e ripristina dalla lunghezza solo durante la decodifica. Lo standard RFC 4648 è competente su entrambi gli alfabeti. La sezione 4 specifica lo standard Base64; la sezione 5 specifica base64url. Ogni decodificatore conforme dovrebbe indicare chiaramente quale alfabeto accetta.
Il codice che accetta Base64url ma non Base64 standard (o viceversa) implementa solo il sottoinsieme. L'alfabeto base64url esiste per compatibilità con URL e vincoli sul nome file; non si tratta di un miglioramento o di una sostituzione, ma solo di una variante per un contesto specifico. Quando crei API o il formato token, scegli un alfabeto e documenta quale. Un errore comune è la codifica percentuale Base64 standard invece di utilizzare base64url. L'implementazione spiega anche il confine dell'articolo. Normalizza il trattino e il carattere di sottolineatura prima della decodifica, ma non verifica la firma del token né interpreta le affermazioni. La conversione di un segmento JWT in byte può rivelare JSON; non è in grado di stabilire chi ha rilasciato JSON o se qualcuno lo ha modificato.
Cosa non copre: verifica delle firme JWT, base32 e delle altre codifiche RFC 4648
%2B è il codice percentuale per +; %2F è il codice percentuale per /. La codifica percentuale trasforma TWFu in TWFu invariato (nessun carattere speciale) ma TE9S+g== in TE9S%2Bg%3D%3D (troppi caratteri da gestire). La soluzione corretta è utilizzare base64url, che produce già l'output URL-safe. La codifica percentuale Base64 è superflua e dispendiosa. Usa l'alfabeto giusto per il contesto. Il codificatore e decodificatore Base64 accetta automaticamente entrambi gli alfabeti.
Se incolli la stringa contenente -, la tratta come base64url; se incolla una stringa contenente +, la tratta come Base64 standard. Lo strumento accetta anche gli URL e li tratta come input URL-safe. Un controllo pratico ha quindi due risultati indipendenti: i byte di andata e ritorno e la rappresentazione scelta si adatta al suo canale. Il superamento del primo dice che la trasformazione è reversibile. Passando il secondo si dice che la punteggiatura e il riempimento non verranno riscritti da URL, nome file, cookie o protocollo che lo trasporta.
Conclusione: due alfabeti, layout a un bit: come il codificatore e decodificatore Base64 gestisce l'alfabeto standard nel browser e dove la pagina degli strumenti indica ciò che accetta
Quando decodifichi il segmento JWT o il token URL-safe, puoi incollarlo direttamente senza conversione e lo strumento identifica l'alfabeto dal contesto. Il debug della decodifica non riuscita diventa semplice: incolla il token, verifica se lo strumento lo accetta e, in caso contrario, scambia manualmente i caratteri e riprova.
La sostituzione stessa è una riga di codice, ma una decodifica non riuscita può anche derivare da una lunghezza impossibile, da un riempimento fuori posto, da corruzione o da input non Base64. Lo strumento normalizza automaticamente entrambi gli alfabeti, quindi l'accettazione conferma solo che i byte possono essere recuperati. Un payload JWT decodificato è ancora un'attestazione non firmata finché un verificatore separato non ne controlla la firma e l'algoritmo previsto.