ECDH (Elliptic Curve Diffie–Hellman) представляет собой механизм установления общего секретного ключа между двумя сторонами по небезопасному каналу связи. В основе лежит асимметричная криптография на эллиптических кривых, обеспечивающая высокую стойкость при относительно небольших размерах ключей и высокой производительности.
В основе алгоритма лежит операция скалярного умножения точки на эллиптической кривой:
Q = d × G
где:
Ключевое свойство:
Это создаёт асимметрию, на которой строится обмен ключами.
ECDH позволяет двум сторонам — условно Alice и Bob — получить одинаковый общий секрет, не передавая его напрямую.
Каждая сторона выполняет одинаковые шаги:
выбирает случайный приватный ключ:
d_A, d_B
вычисляет публичные ключи:
Q_A = d_A × G Q_B = d_B × G
Публичные ключи передаются по открытому каналу.
После обмена публичными ключами:
Alice вычисляет:
S = d_A × Q_B
Bob вычисляет:
S = d_B × Q_A
За счёт свойств эллиптических кривых:
d_A × Q_B = d_A × (d_B × G) = d_B × (d_A × G) = d_B × Q_A
Таким образом обе стороны получают одинаковую точку S, которая используется как общий секрет.
ECDH обеспечивает следующие ключевые свойства:
Компрометация приватного ключа в будущем не раскрывает прошлые сессии при использовании ephemeral-ключей.
Атакующий, имея только публичные ключи, не может вычислить общий секрет без решения задачи дискретного логарифма.
256-битные ключи ECC обеспечивают уровень безопасности, сопоставимый с 3072-битным RSA.
Библиотека SJCL (Stanford Javascript Crypto Library) предоставляет
инструменты для работы с эллиптическими кривыми и ECDH через модуль
sjcl.ecc.
const keypair = sjcl.ecc.elGamal.generateKeys(256);
const publicKey = keypair.pub;
const privateKey = keypair.sec;
В SJCL используется схема ElGamal поверх эллиптических кривых, которая включает ECDH-операции как базовый механизм получения общего секрета.
Обмен ключами в SJCL реализуется через операцию умножения закрытого ключа на публичный ключ другой стороны.
// Alice
const alice = sjcl.ecc.elGamal.generateKeys(256);
// Bob
const bob = sjcl.ecc.elGamal.generateKeys(256);
// Alice вычисляет общий секрет
const secretAlice = alice.sec.dh(bob.pub);
// Bob вычисляет общий секрет
const secretBob = bob.sec.dh(alice.pub);
Обе переменные secretAlice и secretBob
содержат одинаковое значение.
Полученная точка эллиптической кривой не используется напрямую как ключ для AES или других алгоритмов. Обычно выполняется хеширование:
const sharedPoint = alice.sec.dh(bob.pub);
const sharedKeyBits = sjcl.hash.sha256.hash(sharedPoint.toBits());
const aesKey = new sjcl.cipher.aes(sharedKeyBits);
Таким образом обеспечивается:
SJCL поддерживает несколько стандартных кривых, например:
Выбор кривой влияет на:
SJCL использует внутренний формат bitArray:
const bits = sjcl.codec.hex.toBits("a1b2c3d4");
ECDH-результаты также представлены в этом формате, что позволяет легко интегрировать их в хеширование и симметричное шифрование.
Типичный поток выглядит следующим образом:
ECDH сам по себе не защищает от MITM-атак. Без аутентификации злоумышленник может подменить публичные ключи.
Решение:
Использование ephemeral-ключей (одноразовых) предотвращает повторное использование перехваченных сессий.
Криптографическая стойкость напрямую зависит от качества генератора случайных чисел. SJCL использует встроенный CSPRNG, который должен быть корректно инициализирован энтропией.
Использование одного и того же ключа для множества сессий снижает уровень forward secrecy.
Недопустимо использовать результат ECDH без хеширования.
Публичный ключ должен проверяться на принадлежность к корректной кривой.
В практических системах ECDH используется как часть гибридной схемы:
SJCL позволяет реализовать такую схему полностью на стороне JavaScript без внешних зависимостей.
ECDH на эллиптических кривых оптимизирован для:
SJCL реализует оптимизированную арифметику над конечными полями, что уменьшает стоимость вычислений при повторных операциях.
ECDH в SJCL совместим с:
Основное условие — одинаковая кривая и корректная сериализация публичных ключей.
Публичные ключи обычно сериализуются в:
SJCL предоставляет кодеки для преобразования:
sjcl.codec.hex.fromBits(pub.get().x);
ECDH используется в:
Везде применяется вариация ephemeral ECDH для обеспечения forward secrecy.
В клиентских JavaScript-приложениях SJCL позволяет реализовать:
ECDH становится центральным механизмом установления доверенного канала поверх небезопасного HTTP или WebSocket соединения.