Codificador/Decodificador Base64URL

Codifique e decodifique formato Base64URL para transmissão segura em URLs

What is Base64URL Encoding?

Base64URL is a variant of standard Base64 encoding designed specifically for use in URLs and filenames. Defined in RFC 4648 §5, Base64URL replaces the two characters from the standard Base64 alphabet that are problematic in URLs: the plus sign (+) becomes a hyphen (-), and the forward slash (/) becomes an underscore (_). Additionally, Base64URL omits the padding character (=) which would need to be percent-encoded in query strings and path segments, making the encoded output directly usable in URIs without any further escaping.

This distinction is critical in modern web security infrastructure. JSON Web Tokens (JWT), OAuth 2.0 PKCE code verifiers, and WebAuthn credential IDs all mandate Base64URL encoding rather than standard Base64 precisely because these values travel through URLs, HTTP headers, and JSON payloads where +, /, and = have special meaning or require escaping that can break interoperability between systems.

Base64URL vs Standard Base64: Key Differences

Standard Base64 (RFC 4648 §4) uses an alphabet of 64 characters: A–Z, a–z, 0–9, plus (+), and slash (/). It also pads output with equals signs (=) to ensure the encoded length is a multiple of four. While this works well for contexts like MIME email encoding, these three characters cause problems in URLs:

  • Plus sign (+): Interpreted as a space in application/x-www-form-urlencoded form data. Passing a standard Base64 string in a query parameter silently corrupts it when the server decodes spaces back to +.
  • Slash (/): Acts as a path separator in URLs. A Base64 string containing slashes gets fragmented into multiple path segments, breaking routing and parameter extraction.
  • Equals (=): Used as the key-value delimiter in query strings. Padding characters confuse URL parsers and must be percent-encoded as %3D, inflating the encoded size.

Base64URL solves all three issues with minimal changes: replace + with -, replace / with _, and strip all padding. The result is an encoded string that is safe to embed directly in URLs, cookies, HTTP headers, and JSON values without any additional escaping or transformation.

Decoding is equally straightforward: restore any stripped padding (by appending = characters until the length is divisible by 4), replace - with + and _ with /, then decode as standard Base64. This tool handles both directions automatically.

JWT, OAuth, and WebAuthn: Where Base64URL Is Required

The most prominent consumer of Base64URL encoding is the JSON Web Token specification (RFC 7519). A JWT consists of three Base64URL-encoded segments separated by dots: the header, the payload, and the signature. Using standard Base64 here would break token parsing because dots are the only delimiter, and any embedded / or + would corrupt the token when transmitted through URLs or HTTP headers.

OAuth 2.0 also relies on Base64URL in the PKCE (Proof Key for Code Exchange) extension defined in RFC 7636. The code verifier and code challenge values are Base64URL-encoded to ensure they survive URL transport without modification. Using standard Base64 here would introduce characters that require percent-encoding, increasing payload size and creating interoperability issues across implementations.

WebAuthn (the W3C standard for passwordless authentication) encodes credential IDs, attestation objects, and authenticator data using Base64URL. Since these values are exchanged between browsers and relying party servers via JSON APIs and sometimes through URL parameters during redirect flows, the URL-safe alphabet prevents encoding corruption at every hop.

When debugging JWT tokens, OAuth flows, or WebAuthn handshakes, you need a decoder that understands the Base64URL variant specifically — using a standard Base64 decoder on JWT segments will fail or produce garbled output because of the alphabet mismatch and missing padding.

Encoding and Decoding Without Padding

One of the most frequent sources of bugs when working with Base64URL is padding handling. Standard Base64 uses = padding to make the encoded output length a multiple of 4, but Base64URL typically omits it entirely. This means that a Base64URL string can have a length that is not divisible by 4, and decoders must infer the padding from the input length:

  • length % 4 === 0 — no padding needed
  • length % 4 === 2 — add two = characters
  • length % 4 === 3 — add one = character
  • length % 4 === 1 — invalid input (cannot occur in valid Base64URL)

Some implementations are lenient and accept Base64URL input with or without padding. Others are strict and reject padded input. This tool handles both cases: it strips padding during encoding and restores it during decoding, producing correct results regardless of whether the input includes padding characters.

When working across systems (for example, a JWT issued by one library and verified by another), mismatches in padding handling are a common cause of signature verification failures. Always use consistent Base64URL encoding without padding for JWT segments, and ensure your verification library expects unpadded input.

Common Pitfalls and Debugging Tips

Developers frequently encounter issues when mixing standard Base64 with Base64URL. Here are the most common mistakes and how to avoid them:

  • Using btoa()/atob() for JWT segments: The browser's built-in btoa() and atob() functions use standard Base64, not Base64URL. You must convert the alphabet manually or use a dedicated Base64URL library.
  • Forgetting to handle Unicode: Both btoa() and Base64URL operate on byte sequences. For UTF-8 text, encode to bytes first using TextEncoder before Base64URL-encoding, and decode bytes back to text using TextDecoder after Base64URL-decoding.
  • Double-encoding: If a Base64URL string is placed in a URL query parameter that is then additionally percent-encoded, the hyphen and underscore characters (which are URL-safe) get unnecessarily escaped. This produces valid but inefficient output that some parsers may reject.
  • Signature mismatch: When verifying JWT signatures, ensure you decode the signature segment using Base64URL (not standard Base64). A single character difference in the decoded bytes will cause verification to fail.

Code Examples

Base64URL encode and decode in JavaScript

// Encode a string to Base64URL (no padding)
function base64urlEncode(str) {
  const bytes = new TextEncoder().encode(str);
  const binary = String.fromCharCode(...bytes);
  return btoa(binary)
    .replace(/\+/g, '-')   // Replace + with -
    .replace(/\//g, '_')   // Replace / with _
    .replace(/=+$/, '');   // Strip padding
}

// Decode a Base64URL string back to text
function base64urlDecode(base64url) {
  // Restore standard Base64 alphabet and padding
  let base64 = base64url
    .replace(/-/g, '+')
    .replace(/_/g, '/');
  // Add padding if needed
  const pad = base64.length % 4;
  if (pad === 2) base64 += '==';
  else if (pad === 3) base64 += '=';

  const binary = atob(base64);
  const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
  return new TextDecoder().decode(bytes);
}

// Example: JWT-style payload
const payload = JSON.stringify({ sub: "1234", name: "Alice" });
const encoded = base64urlEncode(payload);
// → "eyJzdWIiOiIxMjM0IiwibmFtZSI6IkFsaWNlIn0"

const decoded = base64urlDecode(encoded);
// → '{"sub":"1234","name":"Alice"}'

Decoding JWT segments with Base64URL

// Split a JWT and decode each Base64URL segment
const jwt = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U';
const [headerB64, payloadB64, signatureB64] = jwt.split('.');

// Decode header and payload (both are JSON)
const header = JSON.parse(base64urlDecode(headerB64));
// → { alg: "HS256" }

const payload = JSON.parse(base64urlDecode(payloadB64));
// → { sub: "1234567890" }

// Signature remains as raw bytes (not JSON)
console.log('Signature (Base64URL):', signatureB64);

Standards & Specifications

  • RFC 4648 §5 — Defines the Base64 encoding with URL and filename safe alphabet (Base64URL)
  • RFC 7519 (JWT) — JSON Web Token specification — mandates Base64URL encoding for all three token segments
  • RFC 7636 (PKCE) — OAuth 2.0 PKCE extension — uses Base64URL for code challenge and code verifier values