Структура секретного соглашения Windows CNG ECDH - PullRequest
2 голосов
/ 31 октября 2011

Я потратил несколько дней на поиск структуры секретного соглашения ECDH, но безуспешно.В MSDN я обнаружил, что функция NCryptSecretAgreement устанавливает указатель на переменную NCRYPT_SECRET_HANDLE, которая получает дескриптор, представляющий значение секретного соглашения.Я вообще не знаком с WinAPI, поэтому просто ничего не могу сделать, кроме чтения документов.

Мне нужно обмениваться ключами между настольным приложением на базе Windows и веб-приложением. Мне нужно знать, как именно KDF CNG использует (в моем случае хэши) значение секретного соглашения. Я использую алгоритм SHA-256 в качестве KDF и пытаюсь хэшировать X и Y секретного соглашения.но результат не соответствует тому, который вычисляет КПГ.Есть идеи?

Спасибо.

1 Ответ

1 голос
/ 31 октября 2011

Я не могу поручиться за то, что Microsoft сочла целесообразным реализовать, но есть стандарт на ECDH под названием X9.63 . В этом стандарте ECDH работает так:

  • Вы запускаете вещь DH, получая общую точку кривой (X, Y) (это точка, которую вы получили от пира, умноженная на ваше секретное значение DH).

  • Вы преобразуете X (и только X ; Y отбрасывается) в последовательность байтов, которую мы будем называть Z . Преобразование имеет формат без знака с прямым порядком байтов и использует размер поля: если X живет в поле F q , то преобразование дает ровно ceil (ceil (журнал q) / 8) . Например. если вы используете кривую NIST P-521, вы работаете по модулю простого числа q , которое таково, что 2 520 521 , поэтому ceil (log q) = 521 , а результирующая последовательность байтов состоит ровно из 66 байтов, независимо от значения X . Для наиболее часто используемой эллиптической кривой (известной как «P-256») это составляет 32 байта.

  • Для вывода Z в ключ с хэш-функцией H , длина выходного файла которой составляет n байт (например, n = 32 с SHA-256), вы вычисляете потенциально бесконечную строку H 1 || H 2 || H 3 || ... , где " || " обозначает конкатенацию, а H i = H (Z || i) , где " i"представляется в виде четырех байтов с использованием соглашения с прямым порядком байтов. Проще говоря, вы хешируете Z вместе с 32-битным счетчиком и делаете это снова и снова, пока у вас не будет достаточно байтов для предполагаемой длины ключа.

...