Как конвертировать Base64URL в Base64
- Вставьте Base64URL в поле Ввод · Base64URL. Дополнение не обязательно, стандартные
+и/во входных данных тоже не помешают. - Стандартный Base64 появится в поле Результат · Base64:
-и_заменены на+и/, дополнение восстановлено. - Под результатом Дополнение (=) по умолчанию включено; Перенос строк разбивает результат по 64 символа для PEM или по 76 для MIME.
- Нажмите Скопировать результат. Переключатель Base64 → Base64URL или страница Base64 в Base64URL работают в обратную сторону.
Сколько дополнения добавить
Base64 работает группами по 4 символа. Base64URL обычно отбрасывает знаки =, которые заполняют последнюю группу, так что по длине видно, сколько их вернуть:
| Длина mod 4 | Что добавить | Пример |
|---|---|---|
| 0 | ничего | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 (36 символов) |
| 2 | == | PDw_Pz8-Pg (10) превращается в PDw/Pz8+Pg== |
| 3 | = | eyJyb2xlIjoiYWRtaW4-In0 (23) превращается в eyJyb2xlIjoiYWRtaW4+In0= |
| 1 | недопустимо | один оставшийся символ не вмещает целый байт |
Полезная нагрузка из известного примера eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ занимает 70 символов, остаток 2, значит, к ней добавляется ==. Полное объяснение в статье о дополнении.
Зачем может понадобиться стандартный Base64
Многие декодеры принимают только стандартный алфавит, и на Base64URL они ломаются по-разному:
- GNU coreutils
base64 -dвыводит то, что успел декодировать до первого-или_, а затемbase64: invalid input. - Java
Base64.getDecoder()выбрасываетIllegalArgumentException; для URL-safe входа естьBase64.getUrlDecoder(). - .NET
Convert.FromBase64StringвыбрасываетFormatExceptionна-,_или отсутствующем=. - Python
base64.b64decodeопаснее всех: по умолчанию он молча выбрасывает символы вне стандартного алфавита.b64decode("PDw_Pz8-Pg==")возвращаетb'<<\x0f\xcf\xc3\xe0'вместоb'<<???>>'.
Последний случай стоит покрыть тестом в любом коде, который работает с токенами. Неверные байты без исключения обычно всплывают гораздо позже: не проходит проверка подписи или портятся данные.
Base64URL в Base64 в коде
import base64
def b64url_to_bytes(s: str) -> bytes:
return base64.urlsafe_b64decode(s + "=" * (-len(s) % 4))
b64url_to_bytes("PDw_Pz8-Pg") # b'<<???>>'
base64.b64encode(b64url_to_bytes("PDw_Pz8-Pg")).decode() # 'PDw/Pz8+Pg=='
-len(s) % 4 даёт число недостающих знаков =: 0, 1 или 2 для корректного входа. urlsafe_b64decode требует дополнения, поэтому его добавляют перед вызовом.
function b64urlToB64(s) {
const b = s.replace(/-/g, "+").replace(/_/g, "/");
return b + "=".repeat((4 - (b.length % 4)) % 4);
}
b64urlToB64("PDw_Pz8-Pg"); // 'PDw/Pz8+Pg=='
В Node.js Buffer.from(s, "base64url").toString("base64") делает то же за один вызов. URL-safe декодеры из стандартных библиотек описаны на страницах Python, Java и C#.
Частые проблемы
- «последняя группа символов неполная». Длина даёт остаток 1. Часть строки потерялась, часто на переносе строки или из-за обрезанного URL.
- Символ
.во входных данных. JWT соединяет точками три части в Base64URL. Конвертируйте по одной части или вставьте токен целиком в декодер JWT. %3Dв строке. Значение поверх Base64URL ещё и percent-кодировали. Сначала декодируйте его через URL-декодер.
Вопросы и ответы
Как вернуть дополнение в Base64URL?
Дописывайте =, пока длина не станет кратной 4: два знака при остатке 2 от деления на 4 и один при остатке 3. Остатка 1 в корректных данных не бывает. Этот конвертер сделает всё сам.
Почему base64 -d не справляется с JWT?
GNU base64 -d знает только стандартный алфавит и останавливается с invalid input на первом же - или _. Сначала сконвертируйте часть токена здесь или используйте basenc --base64url -d, который читает URL-safe алфавит.
Что, если в строке на один символ больше?
Строка Base64URL, длина которой даёт остаток 1 при делении на 4, обрезана или содержит лишний символ. Конвертер сообщит о неполной последней группе; проверьте, как значение копировали.
Нужен ли стандартный Base64, чтобы прочитать JWT?
Здесь не нужен: декодер JWT и декодер Base64URL читают Base64URL напрямую. Конвертируйте в стандартный Base64, когда другой инструмент или библиотека принимает только эту форму.