Криптографические примитивы в NaCl работают исключительно с бинарными
данными — массивами байтов (Uint8Array). Однако большинство
прикладных систем, особенно веб-приложения и API, оперируют текстовыми
форматами: JSON, формы, строки URL и базы данных.
Base64 используется как способ безопасного преобразования произвольных бинарных данных в строку, состоящую из печатных символов. Это позволяет:
В контексте TweetNaCl.js Base64 — это вспомогательный слой, не влияющий на криптографию, но необходимый для интеграции.
Библиотека TweetNaCl.js использует собственный набор
утилит в пространстве nacl.util, среди которых:
Uint8Array → Base64Base64 → Uint8ArrayВажно понимать: криптографические функции (box,
secretbox, sign) не работают со
строками. Любая строка Base64 — это лишь представление данных,
а не их форма для вычислений.
Функция преобразует бинарный массив в строку Base64.
nacl.util.encodeBase64(uint8Array)
Uint8ArrayA–Z a–z 0–9 + /=const message = new TextEncoder().encode("hello");
const encoded = nacl.util.encodeBase64(message);
console.log(encoded);
Результат будет строкой Base64, например:
aGVsbG8
(в зависимости от длины данных)
Функция выполняет обратное преобразование — из строки Base64 в бинарный массив.
nacl.util.decodeBase64(base64String)
Uint8Array=const decoded = nacl.util.decodeBase64("aGVsbG8");
const text = new TextDecoder().decode(decoded);
console.log(text); // hello
decodeBase64 строго проверяет входную строку:
Пример некорректного вызова:
nacl.util.decodeBase64("!!!invalid!!!");
Результат: исключение во время декодирования.
В браузерном API существуют встроенные функции:
atob()btoa()Однако они имеют ограничения:
btoa("hello") // работает только с Latin1
Если строка содержит UTF-8 символы — возникает ошибка.
nacl.util.encodeBase64 и decodeBase64
предназначены для бинарных данных и не зависят от текстовой
кодировки.
Base64 в nacl.util используется для:
box.keyPair)и гарантирует корректную двустороннюю совместимость с бинарными алгоритмами.
const keyPair = nacl.box.keyPair();
const publicKeyBase64 = nacl.util.encodeBase64(keyPair.publicKey);
const secretKeyBase64 = nacl.util.encodeBase64(keyPair.secretKey);
Такой формат удобно хранить в базе данных или передавать через API.
const message = nacl.util.decodeUTF8("секрет");
const nonce = nacl.randomBytes(nacl.box.nonceLength);
const encrypted = nacl.box(
message,
nonce,
recipientPublicKey,
senderSecretKey
);
const encodedCipher = nacl.util.encodeBase64(encrypted);
const encodedNonce = nacl.util.encodeBase64(nonce);
const cipher = nacl.util.decodeBase64(encodedCipher);
const nonce = nacl.util.decodeBase64(encodedNonce);
const decrypted = nacl.box.open(
cipher,
nonce,
senderPublicKey,
recipientSecretKey
);
const text = nacl.util.encodeUTF8(decrypted);
Nonce и подписи часто имеют фиксированную длину:
box)Base64 позволяет компактно представлять их:
nacl.util.encodeBase64("hello");
Ошибка: ожидается Uint8Array, а не string.
Правильно:
nacl.util.encodeBase64(nacl.util.decodeUTF8("hello"));
const bad = atob("..."); // приводит к искажению символов
В криптографических данных это недопустимо.
Некоторые внешние системы добавляют = в конце строки.
decodeBase64 TweetNaCl.js может не ожидать padding, что
приводит к ошибкам совместимости.
Base64 в nacl.util работает как два этапа:
И обратно:
Это делает представление примерно на 33% больше по размеру, чем оригинальные данные.
Base64 в криптографических системах обычно используется только на границах системы:
Внутри криптографического процесса всегда остаётся
Uint8Array, так как:
Типичный поток данных:
UTF-8 string
↓ nacl.util.decodeUTF8
Uint8Array
↓ nacl.box / sign / secretbox
Uint8Array (ciphertext)
↓ nacl.util.encodeBase64
Base64 string
И обратный процесс:
Base64 string
↓ decodeBase64
Uint8Array
↓ cryptographic open/decrypt
Uint8Array
↓ encodeUTF8
string