В своем вопросе вы ссылаетесь на статью, объясняющую (классика / МФК) Диффи-Хеллмана, которая является secret = (g ^^ (alice * bob)) % p
.Затем вы упоминаете ECDHE и спрашиваете о классе ECDiffieHellman (Cng) в .NET, который касается эллиптической кривой Диффи-Хеллмана ... варианта ECC алгоритма IFC (Integer Factorization Cryptography).
(IFC)У DH определенно есть проблема с выбором хорошей комбинации (g, p)
, когда человек в середине не обманут.Для TLS серверная часть соединения получает все, что хочет (g, p)
, и затем сообщает клиенту, что оно выбрало, но клиент не может сказать, обманут ли он.Если у вас есть обе стороны, вы можете решить эту проблему, сгенерировав группу качества в 2048-битном пространстве и придерживаясь ее.
В DIFFIE-HELLMAN отсутствует встроенная поддержка (IFC).NET.
ECDH имеет другой набор параметров, которые в совокупности называются «кривая».Для простой кривой (наиболее распространенная форма) параметрами являются кортеж (p, a, b, G, n, h)
(хотя на самом деле n
и h
являются вычислениями из (p, a, b, G)
), а затем математическая математика ECC определяется поверх этой .Как только математика ECC определена, ECDH равен secret = X-Coordinate((alice * bob) * G)
.ECC имеет те же ловушки, что и (IFC) DH, выбор неверных значений для параметров может позволить сыграть трюки с другой стороной.Из-за потенциальной хитрости и большого размера параметров домена выбор параметров домена стандартизируется в «именованные кривые».Два ключа на одной кривой по определению имеют одинаковый набор параметров домена.В TLS вам разрешено использовать только имя (ну, значение Object Identifier) кривой.Сервер в значительной степени выбирает, какой набор параметров, но для максимальной совместимости обычно выбираются только три кривые (по состоянию на 2018 год): secp256r1
(он же NIST P-256), secp384r1
(он же NIST P-384)и secp521r1
(он же NIST P-521).
ECDiffieHellmanCng по умолчанию использует secp521r1
, но вы можете управлять кривой одним из трех способов:
Настройка ecdh.KeySize
Изменение значения KeySize (установка его на любое значение, отличное от того, которое в данный момент хранится) приводит к генерации ключа на кривой этого размера.Это имело смысл для Windows 7, 8 и 8.1 ... потому что Windows CNG поддерживал только secp256r1
, secp384r1
и secp521r1
.Таким образом, вы можете установить KeySize на любой из {256, 384, 521}.
using (ECDiffieHellman ecdh = ECDiffieHellman.Create())
{
ecdh.KeySize = 384;
...
}
Создав его таким образом
В Windows 10 добавлена поддержка большего количества кривых, и размеры стали неоднозначными.256 означает secp256r1
или brainpoolp256r1
(или brainpoolp256t1
, numsp256t1
, secp256k1
, ...)?Хорошо, это означает secp256r1
, и существует более сложный API.
Фабрика ECDiffieHellman.Create
имеет перегрузку (.NET Core 2.1+, .NET Framework 4.7+), которая принимает ECCurve
.Таким образом, другой способ создать кривую над secp384r1
будет
using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP384))
{
...
}
. Его все равно можно будет установить позже
Возможно, вы используете DI и не можете использовать фабрику.Что ж, вы можете использовать метод GenerateKey
(.NET Core 2.1+, .NET Framework 4.7+) для достижения тех же результатов
using (ECDiffieHellman ecdh = ECDiffieHellman.Create())
{
ecdh.GenerateKey(ECCurve.NamedCurves.nistP384);
...
}
Существуют другие способы получения значений ECCurve, напримеркак ECCurve.CreateFromValue("1.3.132.0.34")
или просто вручную создать его из (p, a, b, G = (Gx, Gy), n, h)
.