Алгоритм Elliptic Curve Diffie–Hellman (ECDH) предназначен для безопасного согласования общего секрета между двумя сторонами по открытому каналу. В отличие от классического Diffie–Hellman, он использует арифметику эллиптических кривых, что обеспечивает сопоставимый уровень безопасности при значительно меньших размерах ключей.
Ключевые свойства ECDH:
Эллиптическая кривая задаётся уравнением вида:
y² = x³ + ax + b (mod p)
Где:
p — простое число (модуль поля),a, b — параметры кривой.Операции выполняются над точками кривой:
Приватный ключ — случайное число d, публичный ключ —
точка Q = dG, где G — базовая точка
кривой.
Общий секрет вычисляется как:
S = d_A * Q_B = d_B * Q_A
Библиотека jsrsasign предоставляет инструменты для
работы с эллиптическими кривыми через модуль
KJUR.crypto.ECDSA. Хотя изначально он предназначен для
цифровых подписей, его можно использовать и для ECDH, так как базовые
операции совпадают.
var ec = new KJUR.crypto.ECDSA({ curve: "secp256r1" });
var keypair = ec.generateKeyPairHex();
var privateKeyHex = keypair.ecprvhex;
var publicKeyHex = keypair.ecpubhex;
Особенности:
secp256r1 — одна из наиболее распространённых
кривых;var ecA = new KJUR.crypto.ECDSA({ curve: "secp256r1" });
ecA.setPrivateKeyHex(privateKeyHex);
var ecB = new KJUR.crypto.ECDSA({ curve: "secp256r1" });
ecB.setPublicKeyHex(publicKeyHex);
Методы:
setPrivateKeyHex — установка приватного ключа;setPublicKeyHex — установка публичного ключа.В jsrsasign отсутствует прямой метод ECDH, но можно
воспользоваться внутренними операциями:
function deriveSharedSecret(privKeyHex, pubKeyHex) {
var ec = new KJUR.crypto.ECDSA({ curve: "secp256r1" });
ec.setPrivateKeyHex(privKeyHex);
var pubKey = ec.ecparams.curve.decodePointHex(pubKeyHex);
var d = new BigInteger(privKeyHex, 16);
var sharedPoint = pubKey.multiply(d);
return sharedPoint.getX().toBigInteger().toString(16);
}
Ключевые шаги:
X как общего секрета.// Сторона A
var ecA = new KJUR.crypto.ECDSA({ curve: "secp256r1" });
var keyA = ecA.generateKeyPairHex();
// Сторона B
var ecB = new KJUR.crypto.ECDSA({ curve: "secp256r1" });
var keyB = ecB.generateKeyPairHex();
// Обмен публичными ключами
var sharedA = deriveSharedSecret(keyA.ecprvhex, keyB.ecpubhex);
var sharedB = deriveSharedSecret(keyB.ecprvhex, keyA.ecpubhex);
console.log(sharedA === sharedB); // true
Результат:
Полученный секрет обычно не используется напрямую. Он проходит через KDF (Key Derivation Function).
var sharedHex = sharedA;
var sharedBytes = hextorstr(sharedHex);
var hash = KJUR.crypto.Util.sha256(sharedBytes);
Использование:
Поддерживаются различные форматы:
Пример преобразования:
var pubKeyObj = KEYUTIL.getKey({
xy: publicKeyHex,
curve: "secp256r1"
});
Распространённые варианты:
secp256r1 (P-256) — стандарт NIST;secp384r1 — повышенная безопасность;secp521r1 — максимальная защита;secp256k1 — используется в блокчейн-системах.Влияние выбора:
Критические аспекты:
Проверка точки:
if (!ec.ecparams.curve.validate(pubKey)) {
throw new Error("Invalid public key");
}
1. Использование сырых координат без KDF Приводит к уязвимостям при шифровании.
2. Повторное использование приватного ключа Снижает криптографическую стойкость.
3. Неправильная сериализация ключей Может привести к несовместимости между системами.
4. Игнорирование проверки публичного ключа Открывает возможность атак.
| Характеристика | DH | ECDH |
|---|---|---|
| Размер ключа | большой | маленький |
| Производительность | ниже | выше |
| Уровень безопасности | одинаковый | одинаковый |
| Применение | устаревает | активно используется |
ECDH часто используется совместно с:
Пример:
var aesKey = KJUR.crypto.Util.sha256(sharedHex).substr(0, 32);
Тем не менее, библиотека остаётся мощным инструментом для: