- PVSM.RU - https://www.pvsm.ru -
Эллиптическая криптография, обладая высокой стойкостью и широкой распространенностью, всегда вызывала много споров и спекуляций на предмет возможных закладок для разных кривых и схем подписи. При этом никто не смог привести пример подобной закладки или же доказать их отсутствие. Потому, в отличие от симметричной криптографии, где лидерство безоговорочно принадлежит AES, асимметричная криптография используется разных видов, в зависимости от предпочтений, технических или законодательных требований. Дополнительные типы подписей адресов в I2P предоставляют больший выбор и гибкость для приложений. ГОСТ поддерживается в openssl через EVP интерфейс, однако в версии 1.1 он исключен из стандартной поставки, кроме того существующая реализация предполагает хранение и передачу публичных ключей и подписей в формате DER, а I2P работает непосредственно с числами, определяя необходимые параметры из типа подписи.
В настоящий момент в I2P существует 9 типов подписей [1], где указывается тип подписи, затем тип хэша и, если необходимо, кривая или ее набор параметров.
Также в старых адресах используется тип 0 — DSA_SHA1, считающийся устаревшим.
Рекомендуется использовать типы 1 и 7.
Для ГОСТ-а нам, по моей просьбе, выделено два типа:
9 — GOSTR3410_GOSTR3411_256_CRYPTO_PRO_A
10 — GOSTR3410_GOSTR3411_512_TC26_A
для 256 и 512-битных ключей соответственно.
Длина публичного ключа для 9 составляет 64 байта (по 32 байта на каждую координату точки) и 128 байт для 10.
Предполагается, что подписывается и проверяется хэш длиной 256 или 512 бит. Подробно и с примерами описан здесь [2].
Используется обычная эллиптическая кривая, поэтому для работы с ней могут использоваться функции из криптографической библиотеки. В частности это EC_GROUP_* и EC_POINT_* из openssl, главная из которых это:
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx)
используемая как для умножения базовой точки на число, так и произвольной точки, в зависимости от параметров.
Для кривой задаются 6 параметров: p — модуль, a и b — коэффициенты уравнения кривой, P(x,y) — базовая точка, q — простое число, умножение на которое базовой точки дает нуль.
p и q должны быть большими и близкими к максимальным, поскольку p ограничивает диапазон всех чисел, а q — диапазон секретных ключей. Базовая точка и q вычисляются одновременно.
Как правило используются общеизвестные и хорошо протестированные наборы параметров.
В нашей реализации мы будем использовать 2 набора параметров:
В отличие от кривой, схема подписи в ГОСТ своя, поэтому функции ECDSA_sign и ECDSA_verify использовать нельзя и следует реализовать подпись и проверку подписи в своем коде.
Для подписи (r,s) выбирается случайное число k, и вычисляется точка R=k*P, координата x которой становится компонентой r подписи. Компонента s = r*d + h*k, где d — секретный ключ, h — хэш подписи сообщения в Big Endian.
Для проверки подписи умножим обе части равенства на базовую точку P.
Действительно s*P = r*d*P + h*k*P = r*Q + h*R, где Q — публичный ключ. В этом равенстве нам неизвестна точка R, и хотя можно восстановить координату y по r, это является крайне медленной операцией. Поэтому перепишем равенство в виде h*R = s*P — r*Q, далее
R = (s*P -r *Q)/h и сравнение только координаты x.
bool GOSTR3410Curve::Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s)
{
BN_CTX * ctx = BN_CTX_new ();
BN_CTX_start (ctx);
BIGNUM * q = BN_CTX_get (ctx);
EC_GROUP_get_order(m_Group, q, ctx);
BIGNUM * h = BN_CTX_get (ctx);
BN_mod (h, digest, q, ctx); // h = digest % q
BN_mod_inverse (h, h, q, ctx); // 1/h mod q
BIGNUM * z1 = BN_CTX_get (ctx);
BN_mod_mul (z1, s, h, q, ctx); // z1 = s/h
BIGNUM * z2 = BN_CTX_get (ctx);
BN_sub (z2, q, r); // z2 = -r
BN_mod_mul (z2, z2, h, q, ctx); // z2 = -r/h
EC_POINT * C = EC_POINT_new (m_Group);
EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub
BIGNUM * x = BN_CTX_get (ctx);
GetXY (C, x, nullptr); // Cx
BN_mod (x, x, q, ctx); // Cx % q
bool ret = !BN_cmp (x, r); // Cx = r ?
EC_POINT_free (C);
BN_CTX_end (ctx);
BN_CTX_free (ctx);
return ret;
}
Хотя для подписи сообщения можно использовать любую функцию, вычисляющую хэш подходящего размера, например SHA256/SHA512, мы будем использовать предписываемый стандартом ГОСТ Р 34.11-2012, в том числе и для совместимости с существующими реализациями. В отличие от подписи, хэш устроен много проще.
Подробное описание и примеры [3]. Отметим основные моменты:
Если адрес подключается к маршрутизатору по протоколу I2CP [4], то знание секретного ключа подписи маршрутизатором не требуется.
Вместо этого маршрутизатор отправляет сообщение RequestLeaseSetMessage (или RequestVariableLeaseSetMessage), ожидая в ответ сообщение CreateLeaseSetMessage, содержащее LeaseSet, подписанный секретным ключом адреса. Как можно заметить из описания протокола, в старых версиях I2P требовалось передавать этот ключ в сообщении, больше этого не требуется.
Таким образом, приложение, реализующее I2P адрес, может использовать для подписи API одного из существующих криптопровайдеров с ГОСТ, позволяя эффективно встроить I2P решение в существующую инфраструктуру.
В настоящее время i2pd [5] полностью поддерживает типы подписи 9 и 10. Любые клиентские адреса будут работать с адресами на i2pd. Пример [6] использования. Для работы серверных адресов требуется поддержка со стороны floodfill-ов, либо может быть построенна независимая от основной I2P сеть с netid, отличным от 2. В основной же сети требуется ждать, когда это будет реализовано в джаве [7] или дополнительный параметр floodfill-ов [8].
Автор: orignal
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/c-3/251882
Ссылки в тексте:
[1] 9 типов подписей: https://geti2p.net/spec/common-structures#key-certificates
[2] здесь: http://protect.gost.ru/document.aspx?control=7&id=180151
[3] описание и примеры: http://protect.gost.ru/document1.aspx?control=31&id=180209
[4] I2CP: https://geti2p.net/spec/i2cp
[5] i2pd: https://github.com/PurpleI2P/i2pd
[6] Пример: https://github.com/PurpleI2P/i2pd/wiki/Testing-GOST-R-34.10
[7] реализовано в джаве: https://geti2p.net/spec/proposals/134-gost
[8] дополнительный параметр floodfill-ов: https://geti2p.net/spec/proposals/137-optional-sigtypes
[9] Источник: https://habrahabr.ru/post/325666/
Нажмите здесь для печати.