Функции nacl.box.after и
nacl.box.open.after предназначены для работы с уже
вычисленным общим секретом между двумя сторонами. В основе лежит тот же
механизм асимметричного шифрования, что и в nacl.box,
однако ключевая оптимизация заключается в том, что операция вычисления
общего ключа (shared key) выполняется один раз, а затем
переиспользуется.
Это особенно важно в сценариях:
nacl.box.beforeПеред использованием after-версий необходимо получить
общий ключ:
const sharedKey = nacl.box.before(theirPublicKey, mySecretKey);
Особенности:
Uint8Array длиной 32 байтаПосле этого обе стороны, имея соответствующие ключи, получают
одинаковый sharedKey.
nacl.box.afterconst encrypted = nacl.box.after(message, nonce, sharedKey);
Параметры:
message — Uint8Array, исходные данныеnonce — уникальный 24-байтовый векторsharedKey — заранее вычисленный общий ключРезультат:
Ключевые моменты:
nonce не должен повторяться для одного и того же
ключаnacl.boxnacl.box.open.afterconst decrypted = nacl.box.open.after(encrypted, nonce, sharedKey);
Возвращает:
Uint8Array с исходным сообщением при успешной
проверкеnull, если проверка подлинности не прошлаОсобенности:
nullnacl.box / nacl.box.open| Характеристика | box |
box.after |
|---|---|---|
| Вычисление shared key | каждый вызов | один раз |
| Производительность | ниже | выше при множественных операциях |
| Удобство | проще API | требует подготовки |
| Контроль | меньше | больше |
const alice = nacl.box.keyPair();
const bob = nacl.box.keyPair();
const aliceShared = nacl.box.before(bob.publicKey, alice.secretKey);
const bobShared = nacl.box.before(alice.publicKey, bob.secretKey);
aliceShared и bobShared будут
идентичны.
const nonce = nacl.randomBytes(nacl.box.nonceLength);
const message = new TextEncoder().encode("Привет");
const encrypted = nacl.box.after(message, nonce, aliceShared);
const decrypted = nacl.box.open.after(encrypted, nonce, bobShared);
if (decrypted) {
console.log(new TextDecoder().decode(decrypted));
}
nonce играет критическую роль:
Распространённый подход:
const nonce = nacl.randomBytes(24);
или использование счётчиков (в контролируемых системах).
После вычисления sharedKey можно:
Это превращает асимметричную схему в эффективную симметричную внутри сессии.
Важно учитывать:
sharedKey компрометирует всю сессиюnonce с одним
ключомНе рекомендуется:
sharedKey без шифрованияОсновной выигрыш достигается за счёт:
Типичный сценарий:
beforeafternacl.box.after фактически использует:
Это эквивалентно:
sharedKey = X25519(...)
cipher = XSalsa20(sharedKey, nonce)
mac = Poly1305(ciphertext)
afterПодходит для:
Не подходит, если:
before)after /
open.after1. Перепутаны ключи при before
// неправильно
nacl.box.before(myPublicKey, theirSecretKey)
2. Повторный nonce
// опасно
const nonce = new Uint8Array(24); // всегда нули
3. Игнорирование null при расшифровке
// ошибка
const msg = nacl.box.open.after(...);
// без проверки msg
nacl.box.after и nacl.box.open.after — это
оптимизированный слой поверх стандартного box, превращающий
асимметричное шифрование в эффективный симметричный поток внутри
защищённой сессии.