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

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

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

Под общим значением здесь понимается обычная краска. Фактически это значение мода (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)?

p и g предназначены для IFC Diffie-Hellman, а не для ECC Diffie-Hellman. .NET не имеет общедоступного API для классического DH / IFC. Для ECDH вы выбираете общую кривую, о которой заботятся с помощью ECDiffieHellman.Create (ECCurve) (или установка KeySize для NIST P-256/384/521)

bartonjs 23.10.2018 19:18

Спасибо @bartonjs. Не могли бы вы подробнее объяснить, как задать для KeySize общие значения? Согласно документации, указание размера ключа (256/384/521) создает случайную пару ключей с использованием размера ключа. Достаточно ли использовать один и тот же размер ключей как на стороне клиента, так и на стороне сервера для генерации случайных пар ключей? Если мы обмениваемся этими открытыми ключами, а затем обе стороны получат секретный ключ, используя другой открытый ключ, будут ли они одинаковыми?

bdotnet 24.10.2018 10:55

Ага. Это единственные три разрешенных числа.

bartonjs 24.10.2018 15:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
1 611
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

Спасибо @kelalaka. У меня вопрос - где мы настраиваем эти значения в коде? Все, что мы делаем здесь, - это создаем новый экземпляр ECDiffieHellmanCng на стороне клиента и на стороне сервера. Что гарантирует, что оба используют одинаковые значения p и g?

bdotnet 23.10.2018 08:34

Вы же распространяете код? поэтому укажите эти значения как для сервера, так и для клиента. Все должны согласовать параметры для обмена ключами.

kelalaka 23.10.2018 16:12
Ответ принят как подходящий

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

(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 вам разрешено использовать только имя (ну, значение идентификатора объекта) кривой. Сервер в значительной степени может выбирать, какой набор параметров, но для максимальной совместимости обычно выбираются только три кривые (по состоянию на 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).

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