Кодирование и безопасность

Base64 не шифрование: зачем он нужен и чем пользоваться, когда действительно нужна секретность

Base64 превращает байты в текст, чтобы они прошли через системы, рассчитанные на текст. Обратить его можно одним вызовом. Где он уместен (почта, JSON, data URL), во что обходятся 33 % и чем различаются кодирование, хеширование и шифрование.

Коротко

Base64 позволяет записать любую последовательность байтов 64 безопасными символами (A–Z, a–z, 0–9, +, /). Он нужен, чтобы двоичные данные (картинка, PDF, ключ) могли пройти через системы, которые понимают только текст: тело письма, строки JSON, URL, атрибуты HTML. Это кодирование, а не шифрование: ключа нет, а декодирование выполняется одним вызовом функции, доступной в любом языке и в консоли разработчика любого браузера. Пароль, сохранённый «в Base64», хранится открытым текстом, просто с лишними шагами.

Зачем он появился

Электронную почту в 1970-х проектировали под 7-битный ASCII. Когда появились вложения (MIME, 1992), байты JPEG пришлось маскировать под безобидный текст: они используют все 256 значений, включая те, что почтовый сервер понимает как «конец строки» или «конец письма». Ответом стал Base64: берутся три байта (24 бита), делятся на четыре группы по 6 бит, и каждая группа заменяется одним из 64 символов. Каждые 3 байта превращаются в 4 символа. Отсюда знаменитые 33 % накладных расходов: вложение на 3 МБ даёт письмо на 4 МБ, и поэтому в лимит почты «25 МБ» помещается файл на 18 МБ.

Тот же приём встречается везде, где единственный канал текстовый: небольшая картинка прямо внутри веб-страницы (data:image/png;base64,…), двоичный токен в HTTP-заголовке (Authorization: Basic …), сертификаты и ключи в файлах PEM, массив байтов в поле JSON.

Варианты, на которых спотыкаются

  • Стандартный и URL-safe. Стандартный Base64 использует + и /, а оба символа в URL имеют особый смысл. Алфавит URL-safe (RFC 4648 §5) заменяет их на - и _. Токен, закодированный одним вариантом и декодируемый другим, ломается именно на этих двух символах. JWT используют URL-safe.
  • Выравнивание. Длина результата всегда кратна четырём и дополняется знаками =. Некоторые генераторы отбрасывают выравнивание (опять JWT), а некоторые декодеры его требуют. Если корректная в остальном строка не декодируется, добавляйте =, пока длина не станет кратной четырём.
  • Перенос строк. MIME переносит строки через 76 символов, PEM через 64. Декодеры обычно игнорируют пробельные символы, но не все.
  • Кодировка текста под ним. Base64 кодирует байты. Чтобы закодировать строку, её сначала переводят в байты, и выбор между UTF-8, UTF-16 и Latin-1 меняет результат. Классическая ошибка JavaScript, когда btoa("é") выбрасывает исключение, возникает именно поэтому: btoa принимает только Latin-1. Сначала получите байты UTF-8.

Base64: кодирование поддерживает оба алфавита, выравнивание, перенос строк и UTF-8 и декодирует как в текст, так и в файл для скачивания, поэтому data: URL или вложение из письма можно превратить обратно в исходный файл прямо в браузере.

Кодирование, хеширование, шифрование

В обиходных текстах эти три слова путают, хотя означают они совершенно разные вещи.

Обратимо? Нужен ключ? Назначение
Кодирование (Base64, hex, URL-кодирование) Да, кем угодно Нет Подогнать данные под канал
Хеширование (SHA-256, MD5) Нет Нет Получить отпечаток данных, проверить, что они не изменились
Шифрование (AES, RSA) Да, с ключом Да Скрыть данные от всех, у кого нет ключа

Хеш файла позволяет проверить, что скачанное совпадает с тем, что выложил издатель. Хеши (MD5, SHA-256) считает MD5, SHA-1 и SHA-256/384/512 в браузере и сравнивает результат с вставленной контрольной суммой. Ничего при этом не скрывается: файл остаётся тем же файлом. Секретность из трёх вариантов даёт только шифрование, и оно надёжно ровно настолько, насколько надёжен ключ. Здесь и пригодится действительно случайный пароль.

Если вы собирались закодировать секрет в Base64

Не надо. В частности:

  • Конфигурационные файлы с паролями в Base64 (распространённая практика в старых приложениях на Java и .NET) содержат пароли открытым текстом для любого, кто откроет файл.
  • «Замаскированные» ключи API во фронтенд-JavaScript видны на вкладке сети, в Base64 они или нет.
  • Basic-аутентификация по обычному HTTP передаёт имя пользователя и пароль в Base64, то есть фактически открытым текстом. Она допустима только внутри HTTPS, где шифрованием занимается транспорт.

Если данные нужно хранить или передавать в секрете, зашифруйте их настоящим шифром (AES-256-GCM через криптобиблиотеку платформы), а затем, если они должны пройти по текстовому каналу, закодируйте шифротекст в Base64. Кодировать после шифрования нормально. Ошибка в том, чтобы кодировать вместо шифрования.

Озвучка текстаTextToSpeech.tools Сжать видеоFreeCompress.video Китайско-английский словарьChineseDict.com