Функция nacl.box.open предназначена для
расшифровки сообщения и одновременной проверки его
подлинности. Она является обратной операцией к
nacl.box и используется в асимметричной криптографии на
основе кривой Curve25519 и алгоритма XSalsa20-Poly1305.
Ключевая особенность: расшифровка выполняется только если
сообщение прошло аутентификацию. В противном случае функция
возвращает null.
nacl.box.open(box, nonce, publicKey, secretKey)
Параметры:
box — зашифрованное сообщение (Uint8Array)nonce — одноразовый номер (Uint8Array длиной 24
байта)publicKey — публичный ключ отправителя (Uint8Array
длиной 32 байта)secretKey — приватный ключ получателя (Uint8Array
длиной 32 байта)Возвращаемое значение:
Uint8Array с расшифрованными данными при успехеnull при ошибке аутентификации или повреждении
данныхПроцесс nacl.box.open включает два этапа:
Вычисление общего секрета (shared key) Используется алгоритм Диффи–Хеллмана на Curve25519:
sharedKey = scalarMult(secretKey_receiver, publicKey_sender)Расшифровка и проверка MAC С помощью XSalsa20 выполняется расшифровка, а Poly1305 проверяет целостность и подлинность.
Если MAC (Message Authentication Code) не совпадает — данные считаются поддельными.
nacl.box.open обеспечивает:
Важно: функция не различает тип ошибки — это сделано намеренно для предотвращения атак по побочным каналам.
const nacl = require('tweetnacl');
// Генерация ключей
const alice = nacl.box.keyPair();
const bob = nacl.box.keyPair();
// Сообщение
const message = new TextEncoder().encode("Secret message");
// nonce
const nonce = nacl.randomBytes(nacl.box.nonceLength);
// Шифрование (Алиса → Боб)
const encrypted = nacl.box(
message,
nonce,
bob.publicKey,
alice.secretKey
);
// Расшифровка (Боб)
const decrypted = nacl.box.open(
encrypted,
nonce,
alice.publicKey,
bob.secretKey
);
if (decrypted) {
console.log(new TextDecoder().decode(decrypted));
} else {
console.log("Ошибка аутентификации");
}
Если:
то результат будет:
null
Это критически важно: никаких исключений не выбрасывается — только
null.
nonce (number used once) — обязательный параметр,
который:
Повторное использование nonce с теми же ключами разрушает безопасность.
nacl.box.open без проверки
результатаnullnacl.secretbox.open| Характеристика | nacl.box.open | nacl.secretbox.open |
|---|---|---|
| Тип криптографии | Асимметричная | Симметричная |
| Ключи | Пара ключей | Один общий ключ |
| Аутентификация | Да | Да |
| Использование | Обмен между сторонами | Локальное шифрование |
Для повышения производительности при множественных сообщениях:
const sharedKey = nacl.box.before(theirPublicKey, mySecretKey);
const decrypted = nacl.box.open.after(
box,
nonce,
sharedKey
);
Преимущества:
Uint8Arrayconst encoder = new TextEncoder();
const decoder = new TextDecoder();
1. Перепутаны ключи
// Неверно
nacl.box.open(box, nonce, myPublicKey, theirSecretKey);
Ключи должны быть:
2. Использование строки вместо Uint8Array
// Неверно
nacl.box.open("encrypted", nonce, pub, sec);
3. Игнорирование результата
const result = nacl.box.open(...);
// Нет проверки на null — потенциальная уязвимость
nacl.box.open выполняет строгую проверку MAC. Даже
изменение одного бита приведёт к отказу:
encrypted[0] ^= 1;
const result = nacl.box.open(...);
// result === null
Зашифрованное сообщение включает:
Именно MAC проверяется перед расшифровкой.
nacl.randomBytesnullbox.before при большом объёме
сообщенийnacl.box.open объединяет:
Эта комбинация известна как crypto_box в библиотеке NaCl.
nacl.boxbox + nonce + publicKeynacl.box.openbefore/after снижает накладные
расходыТак как используется публичный ключ отправителя, получатель может быть уверен:
Эти задачи решаются на уровне протокола.
nacl.box.open совместим с:
при условии:
Uint8Arraynull