Одно кодирование, два алфавита

Base64 превращает произвольные байты в 64 печатных символа, четыре выходных символа на каждые три входных байта. Стандартный алфавит (RFC 4648, раздел 4) — это AZ, az, 09 и два символа + и /, где = используется для заполнения последней группы.

Проблема в том, что +, / и = имеют особые значения в других контекстах. В URL / — разделитель пути, + исторически означает пробел в строках запроса, а = отделяет ключ от значения. В имени файла / недопустим в большинстве систем. Поэтому чистый Base64 нельзя поместить в URL или имя файла без искажения или дополнительного экранирования.

Что меняет Base64URL

Base64URL (RFC 4648, раздел 5) — то же кодирование с более безопасным алфавитом. Отличаются ровно два символа:

  • + становится - (дефис)
  • / становится _ (подчёркивание)

Все остальные символы идентичны, и арифметика «три байта в четыре символа» не меняется. В результате получается строка, которая переживает размещение в пути URL, параметре запроса или имени файла без какого-либо процентного кодирования.

Заполнение — второе отличие. Стандартный Base64 дополняет последнюю группу до кратной четырём с помощью =. Base64URL обычно полностью опускает заполнение, потому что = тоже неудобен в URL. Декодер всегда может пересчитать, сколько заполнения было убрано, по длине строки, так что ничего не теряется.

Где это действительно встречается

Base64URL — не экзотический уголок спецификации. Это кодирование, стоящее за несколькими вещами, которыми вы пользуетесь постоянно:

  • JSON Web Tokens. состоит из трёх сегментов Base64URL, соединённых точками (header.payload.signature). Замена +// и опущенный = — именно поэтому токен является одной чистой, безопасной для URL строкой.
  • . code_challenge в потоке кода авторизации — это кодирование Base64URL (без заполнения) хеша , именно чтобы он мог путешествовать в URL.
  • Web Push, и многие токены кодируют свои двоичные поля так же.

Практическое предостережение

Поскольку алфавиты сильно пересекаются, строка Base64URL и стандартная строка Base64 могут выглядеть почти одинаково, и значение без +, / или = допустимо в обоих. Несовместимость проявляется лишь тогда, когда сырые байты дают -/_ или +//, и тогда декодирование неправильным алфавитом терпит неудачу или выдаёт мусор. Когда токен не декодируется, алфавит — первое, что нужно проверить.

Инструмент Base64 кодирует и декодирует как стандартный, так и безопасный для URL алфавит, обрабатывает отсутствующее заполнение и показывает сырые байты — всё в вашем браузере. Ничего из вставленного никуда не отправляется.