Эфемерные ключи — это временные криптографические ключи, создаваемые на короткий срок и используемые, как правило, в рамках одной сессии или даже одного сообщения. В отличие от долговременных (static) ключей, они не сохраняются после завершения взаимодействия и не используются повторно.
В библиотеке TweetNaCl.js эфемерные ключи создаются стандартными средствами генерации ключевых пар:
const nacl = require('tweetnacl');
const ephemeralKeyPair = nacl.box.keyPair();
Каждый вызов keyPair() генерирует новую пару:
publicKey — может быть передан другой сторонеsecretKey — должен оставаться строго
конфиденциальнымКлючевой особенностью является отсутствие повторного использования. Это критически важно для обеспечения криптографической стойкости.
Forward secrecy — это свойство криптографической системы, при котором компрометация долговременного секретного ключа не позволяет расшифровать ранее перехваченные сообщения.
Это достигается за счёт:
Даже если злоумышленник получит доступ к приватному ключу спустя время, он не сможет восстановить сессионные ключи, использованные ранее.
В TweetNaCl.js механизм обмена ключами и шифрования реализован через
nacl.box, который использует:
Каждая сторона генерирует временную ключевую пару:
const aliceEphemeral = nacl.box.keyPair();
const bobEphemeral = nacl.box.keyPair();
Для шифрования сообщения используется комбинация:
const nonce = nacl.randomBytes(nacl.box.nonceLength);
const messageUint8 = new TextEncoder().encode("secret message");
const encrypted = nacl.box(
messageUint8,
nonce,
bobEphemeral.publicKey,
aliceEphemeral.secretKey
);
Расшифровка выполняется с использованием:
const decrypted = nacl.box.open(
encrypted,
nonce,
aliceEphemeral.publicKey,
bobEphemeral.secretKey
);
Для повышения производительности при множественных операциях между
одними и теми же ключами используется nacl.box.before:
const sharedKey = nacl.box.before(
bobEphemeral.publicKey,
aliceEphemeral.secretKey
);
После этого можно использовать:
nacl.box.after для шифрованияnacl.box.open.after для расшифровкиconst encrypted = nacl.box.after(messageUint8, nonce, sharedKey);
Однако при использовании эфемерных ключей это преимущество минимально, так как ключи не переиспользуются.
На практике часто используется гибридный подход:
Это позволяет:
Эфемерные ключи могут использоваться не только на уровне сессии, но и на уровне сообщений.
Пример:
const oneTime Key = nacl.box.keyPair();
const encrypted = nacl.box(
messageUint8,
nonce,
recipientPublicKey,
oneTimeKey.secretKey
);
Получатель использует переданный публичный ключ:
const decrypted = nacl.box.open(
encrypted,
nonce,
oneTimeKey.publicKey,
recipientSecretKey
);
Критические аспекты:
В JavaScript нет прямого контроля над очисткой памяти, поэтому рекомендуется:
Повторное использование эфемерных ключей Сводит на нет forward secrecy и может привести к компрометации сообщений.
Использование слабых генераторов случайных чисел TweetNaCl.js использует криптографически стойкий генератор, но при работе в нестандартных окружениях это требует проверки.
Хранение приватных ключей Даже временные ключи не должны записываться в лог или кэшироваться.
Типичный поток:
Такой подход:
Это означает, что:
Эфемерные ключи в TweetNaCl.js могут служить основой для:
Однако такие механизмы, как:
должны реализовываться поверх библиотеки, поскольку TweetNaCl.js не предоставляет их из коробки.