id: Гость   вход   регистрация
текущее время 19:14 19/11/2019
создать
просмотр
редакции
ссылки

Код асимметричного крипто


Одним из разделов, проверенных нами в первую очередь, был код, ответственный за криптографию с открытым ключом. Причины в том, что, во-первых, это очень компактный предмет (соответствующий код просто найти и его объём невелик) и, во-вторых, очень многое в нём можно сделать неверно. А на используемые там числа накладывается целое множество требований (быть простыми, относительно простыми, случайными, ненулевыми, не слишком малыми и т.д.).


PK-код можно найти в директории /libs/pgpcdk/priv/keys/pubkey

RSA


Вследствие того, что программа поддерживает разные библиотеки, реализующие RSA, исходный код довольно запутан. pgpaltrsaglue.c использует криптобиблиотеку RSAREF производства RSA Data Security. Этот файл не используется при стандартных настройках. То же самое касается pgpBRSAGlue.c, использующего библиотеку BSAFE, также от RSA Data Security. Следующий файл, pgpMSRSAGlue.c, полагается на интерфейс Microsoft CryptoAPI; он тоже не используется при обычных настройках (уф!). Единственный активный файл — это pgpRSAGlue, который использует собственный код PGP для работы с большими числами, являющийся из всех ещё и самым быстрым.


Не думаю, что кто-нибудь захочет использовать альтернативные библиотеки. Их поддержка присутствует из-за прежних юридических проблем, которые ныне разрешены. Альтернативные библиотеки медленнее реализации PGP, а некоторые накладывают дополнительные ограничения на предельную длину ключа.


Весьма небезынтересен файл pgpRSAkey.c: он содержит процедуры для генерации ключей RSA. PGP получает большие числа, генерируя вначале случайное число заданного размера, а затем устанавливая его младший бит (чтобы сделать нечётным) и два старших бита. Старший бит необходимо установить, чтобы получить число необходимой длины. Установка второго значащего бита не совсем понятна: в комментарии говорится, что это гарантирует получение числа высокого порядка, которое труднее факторизовать, но мне кажется, что установка этих двух битов обеспечивает произведение n требуемой длины (может статься, что, умножив два 512-битовых числа, вы получите число в 1023 бита, а это, как правило, не то, чего бы вам хотелось). Простое число, чуть большее первоначального случайного числа, возвращается функцией bnPrimeGen (не всегда первое же простое число, поскольку она перебирает 256 чисел от точки отсчёта).


Забавно, но изучение конкретных деталей раскрывает некоторые биты числа n. Поскольку q,p > 3∗2512, это значит, что n > 9∗21024, следовательно, n не может начинаться с битов 1000.


В качестве e используется фиксированная константа RSA_DEFAULT_EXPONENT. В исходном тексте она равна 17, но в установленном у меня PGP7 имеет значение 65537.


В исходнике содержится баг: сгенерировав q, программе следует убедиться, что НОД(e,q-1) == 1. Этого, однако, не происходит. Строка 1454 гласит:



Вместо проверки q она перепроверяет p. Строка должна иметь вид:



Подобный тест избыточен, поскольку функция bnPrimeGen может принимать e в качестве дополнительного аргумента, что заставляет её сгенерировать такое простое число, для которого e будет обратимым: функция обеспечивает удовлетворение условиям на этапе генерации, так что последующая проверка бессмысленна. Таким образом, эксплуатировать данный баг невозможно, но сам факт, что баг может быть найден в столь критичной части PGP, вызывает беспокойство.

DSA


Исходный код для алгоритма подписи DSA находится в файле pgpDSAkey.c. PGP выполняет проверки, необходимые для сличения подписи (r,s < q). Заметьте, что PGP не может работать с отрицательными большими числами; это делает оправданным отсутствие проверки на положительность, что довольно необычно и является плюсом к безопасности PGP, ведь большинство математических библиотек универсальны и допускают отрицательные числа.


Комментарии, окружающие код DSA, обосновывают и существование "ложного" пула: из-за того, что открытые параметры ключа генерируются одновременно с секретным параметром x, разработчики опасались, что, теоретически, будет возможно восстановить состояние пула случайных чисел по материалу открытого ключа (взломав хэш-функцию, что само по себе непросто). Чтобы не допустить этого, они решили генерировать открытые параметры из очень небольшого фрагмента пула, благодаря чему открытые параметры должны представлять лишь малую часть пула случайных чисел. "Ложный" генератор инициализируется 64 битами реального пула. Такая длина не является непредсказуемой (80 бит считается безопасным), но мы здесь добиваемся другого: 64 бита гарантируют, что всякий раз мы получим уникальные публичные параметры. Не забывайте, что даже использование одинаковых публичных параметров не считается риском: алгоритм допускает работу с общими параметрами. Просто таковые становятся более привлекательной мишенью для взломщика. (Если бы PGP использовал общие параметры открытых ключей, поползли бы слухи о потайном ходе в программе.)


Назад | Дальше


 
Комментариев нет [показать комментарии/форму]
Ваша оценка документа [показать результаты]
-3-2-1 0+1+2+3