Использование ECDiffieHellmanCng для обмена ключами

Мы планируем использовать алгоритм ECDHE для обмена ключами между клиентом и сервером, чтобы оба они могли получить общий секретный ключ для шифрования сообщений.

Исходя из того, что я прочитал, чтобы использовать алгоритм ECDHE, обе стороны (клиент и сервер) должны сначала согласовать пару "общих" значений (p, g). Затем каждая сторона будет использовать закрытый ключ для генерации общего ключа, т.е. клиент использует закрытый ключ (P1) для генерации общего ключа (S1), а сервер использует закрытый ключ (P2) для генерации общего ключа (S2). Ссылка: [ https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange

Общая ценность здесь относится к общей краске. Это на самом деле значение мода (p) и базовое значение (g), используемые обеими сторонами для генерации общих ключей.

Затем обе стороны обмениваются общими ключами (S1 и S2) и используют его со своим собственным закрытым ключом (P1 или P2) для получения общего секрета (K)

Когда я смотрю на примеры, которые используют ECDiffieHellmanCng для генерации ключей, я не вижу возможности указать эти "общие" значения где-либо. В нашем случае я ожидал, что и клиент, и сервер согласятся с p и g, а затем используют эти значения с "ECDiffieHellmanCng" для генерации общего общего ключа.

Ссылка: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.ecdiffiehellmancng?view=netframework-4.7.2

Я вижу, как Алиса и Боб создают новый экземпляр ECDiffieHellmanCng - они оба используют одни и те же общие значения (p и g)?

2 ответа

Решение

В своем вопросе вы ссылаетесь на статью, объясняющую (классика / МФК) Диффи-Хеллмана, которая является secret = (g ^^ (alice * bob)) % p, Затем вы упоминаете ECDHE и спрашиваете о классе ECDiffieHellman(Cng) в.NET, который касается эллиптической кривой Диффи-Хеллмана... варианта ECC алгоритма IFC (целочисленная факторизационная криптография).

(IFC) У DH определенно есть проблема с выбором хорошего (g, p) комбинация, и не быть обманутым человеком в середине. Для TLS серверная часть соединения получает все (g, p) он хочет, а затем сообщает клиенту, что он выбрал, но клиент не может сказать, обманут ли он. Если у вас есть обе стороны, вы можете решить эту проблему, создав группу качества в 2048-битном пространстве и придерживаясь ее.

В.NET отсутствует поддержка (IFC) Диффи-Хеллмана, входящая в комплект поставки.

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),

  • GF(q) обозначает конечное поле с q элементами
  • р является базовой точкой

Да, они должны использовать ту же базовую точку и ту же эллиптическую кривую E над полем Fq. это общедоступные.

Другие вопросы по тегам