В криптографической модели TweetNaCl.js ключи являются базовым строительным элементом для всех операций: шифрования, подписи и обмена данными. Библиотека реализует компактную версию NaCl (Networking and Cryptography library), где каждая криптосхема опирается на строго определённые типы ключей.
Для асимметричного шифрования используется схема Curve25519 через
nacl.box.keyPair().
const nacl = require('tweetnacl');
const keyPair = nacl.box.keyPair();
const publicKey = keyPair.publicKey;
const secretKey = keyPair.secretKey;
Свойства:
publicKey — открытая часть, передаётся другим
участникамsecretKey — приватная часть, должна оставаться строго
локальнойКлючевая пара используется для:
Для цифровой подписи используется Ed25519:
const signKeyPair = nacl.sign.keyPair();
const publicKey = signKeyPair.publicKey;
const secretKey = signKeyPair.secretKey;
Особенность модели:
Используется для:
Для симметричного шифрования применяется nacl.secretbox,
где ключ уже не разделяется на пары:
const key = nacl.randomBytes(32);
Используется единый ключ:
Модель основана на комбинации:
const nonce = nacl.randomBytes(24);
const message = new TextEncoder().encode("data");
const encrypted = nacl.box(
message,
nonce,
receiverPublicKey,
senderSecretKey
);
const decrypted = nacl.box.open(
encrypted,
nonce,
senderPublicKey,
receiverSecretKey
);
Ключевой принцип: Каждая сторона использует свою секретную часть и публичную часть собеседника.
const nonce = nacl.randomBytes(24);
const key = nacl.randomBytes(32);
const encrypted = nacl.secretbox(message, nonce, key);
const decrypted = nacl.secretbox.open(encrypted, nonce, key);
Особенности:
const signed = nacl.sign(message, secretKey);
const verified = nacl.sign.open(signed, publicKey);
Свойства:
JavaScript не предоставляет прямого управления памятью. Это означает:
Наиболее безопасный вариант — хранение только в RAM:
let secretKey = nacl.box.keyPair().secretKey;
Особенности:
Прямое хранение криптографических ключей в браузере связано с рисками:
localStorage доступен через JavaScript любого скрипта
страницыПример небезопасного хранения:
localStorage.setItem(
"secretKey",
JSON.stringify(Array.from(secretKey))
);
Более устойчивый вариант — использование IndexedDB с дополнительным шифрованием ключа другим паролем пользователя.
В серверных приложениях ключи обычно:
TweetNaCl.js использует Uint8Array. При хранении часто
применяются преобразования:
function encodeKey(key) {
return Buffer.from(key).toString("base64");
}
function decodeKey(str) {
return new Uint8Array(Buffer.from(str, "base64"));
}
JavaScript не гарантирует физическое обнуление памяти после удаления переменной:
secretKey = null;
Это:
Для уменьшения риска утечки используется ручное обнуление:
function wipe(array) {
for (let i = 0; i < array.length; i++) {
array[i] = 0;
}
}
Применение:
wipe(secretKey);
secretKey = null;
Генерация
Использование
Промежуточное хранение
Удаление ссылок
Попытка перезаписи памяти
В JavaScript невозможно гарантировать:
Ключи различаются по назначению:
Чем меньше ключ существует в памяти, тем ниже риск компрометации. Типичная модель:
Ключи не должны смешиваться с:
Типовые проблемы:
// опасное копирование
const copy = [...secretKey];
GC в V8:
Это делает невозможным строгий контроль над физическим расположением ключей.
Криптографический ключ в TweetNaCl.js проходит через последовательность состояний:
Полный контроль достигается не механизмами языка, а архитектурными решениями: минимизацией времени жизни, ограничением копирования и исключением долгосрочного хранения в небезопасных средах.