ECDH (Elliptic Curve Diffie-Hellman) — алгоритм, позволяющий двум
сторонам вычислить общий секрет по открытым параметрам, не передавая сам
секрет по сети. В Web Crypto API он используется через интерфейс
SubtleCrypto, доступный как crypto.subtle.
subtle.generateKeyМетод генерации ключей имеет универсальную форму:
crypto.subtle.generateKey(
algorithm,
extractable,
keyUsages
)
Для ECDH параметры имеют строго определённую структуру.
Объект конфигурации алгоритма:
{
name: "ECDH",
namedCurve: "P-256"
}
Поддерживаемые кривые:
"P-256" — наиболее распространённая, баланс между
безопасностью и производительностью"P-384" — повышенный уровень криптографической
стойкости"P-521" — максимальная стойкость среди стандартных
кривых, но более медленнаяВыбор кривой влияет на размер ключей и вычислительную нагрузку.
true | false
Определяет, можно ли экспортировать ключи из объекта
CryptoKey.
true — ключ можно извлечь (например, для хранения или
передачи)false — ключ остаётся внутри Web Crypto и не может быть
экспортированВ реальных криптографических системах чаще используется
false для приватных ключей.
Массив допустимых операций для ключа.
Для ECDH доступны:
"deriveKey" — создание симметричного ключа на основе
ECDH"deriveBits" — получение «сырых» байтов общего
секретаПример:
["deriveKey", "deriveBits"]
Метод возвращает Promise, который разрешается в
объект:
CryptoKeyPair
Структура:
{
publicKey: CryptoKey,
privateKey: CryptoKey
}
publicKey — можно передавать другой сторонеprivateKey — должен оставаться в безопасности и не
покидать контекстconst keyPair = await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-256"
},
false,
["deriveKey", "deriveBits"]
);
console.log(keyPair.publicKey);
console.log(keyPair.privateKey);
После выполнения создаётся пара ключей, связанных между собой математически, но не позволяющих восстановить приватный ключ из публичного.
Сгенерированная пара не используется напрямую для шифрования. Её задача — создание общего секрета с другой стороной.
Типичный поток:
deriveBits или
deriveKeyconst aliceKeys = await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-256"
},
false,
["deriveKey", "deriveBits"]
);
const bobKeys = await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-256"
},
false,
["deriveKey", "deriveBits"]
);
Для обмена ключами публичная часть обычно экспортируется:
const exportedPublicKey = await crypto.subtle.exportKey(
"spki",
aliceKeys.publicKey
);
Формат "spki" используется для асимметричных публичных
ключей.
CryptoKey — это объект-обёртка, внутри которого хранится
материал ключа в защищённом виде.
Даже при наличии публичного ключа вычислить приватный невозможно при корректной реализации ECDH и использовании стандартных кривых.
Они не сериализуются напрямую через JSON.stringify и не
могут быть клонированы стандартными методами.
namedCurve: "secp256k1" // не поддерживается в большинстве браузеров
Результат: NotSupportedError
["encrypt"]
ECDH не предназначен для прямого шифрования, поэтому будет ошибка.
Даже при правильной логике:
extractable: false
экспорт приватного ключа невозможен.
ECDH в Web Crypto API почти всегда используется как этап гибридной криптографии:
Хотя generateKey создаёт пару, основной практический
смысл раскрывается через:
subtle.deriveKeysubtle.deriveBitsИменно они превращают ECDH в механизм установления общего ключа шифрования.
extractable: falsegenerateKey → создание пары ECDHexportKey (publicKey) → обменimportKey (publicKey другой стороны)deriveBits или deriveKey → общий
секрет