В чем разница между NID_sha и NID_sha1 в Openssl - PullRequest
3 голосов
/ 07 апреля 2011

Страница man для RSA_sign () говорит о параметре типа:

type denotes the message digest algorithm that was used to generate m. It usually is one of NID_sha1, NID_ripemd160 and NID_md5; see objects(3) for details.

Но я вижу другой доступный тип - NID_sha в исходном коде Openssl.Может кто-нибудь помочь мне с разницей между этими двумя?

Я планирую использовать функцию RSA_Sign, чтобы подписать дайджест SHA-256, SHA-512, но я не вижу соответствующего параметра типа для SHA-256 и SHA-512, так что мне следует вводить для параметра типа в этих случаях.

Пока я использовал тип как NID_sha и попытался подписать хеш SHA-256, SHA-512 и для него обоихработает успешно, что дает правильную подпись, и более поздняя проверка подписи также правильна, но я просто хотел бы знать, что такое NID_sha?

Любая помощь будет принята с благодарностью.Спасибо!

1 Ответ

11 голосов
/ 07 апреля 2011

NID_sha обозначает SHA-0, прямого предка SHA-1. SHA-0 первоначально назывался «SHA», но вскоре была опубликована модифицированная версия, названная SHA-1; предыдущий «SHA» был тогда объявлен устаревшим и теперь традиционно называется «SHA-0». Фактическая причина изменения не была официально озвучена, но было общепринято, что SHA-0 имел какую-то слабость - которая была обнаружена независимыми исследователями несколько лет спустя и использовалась для создания столкновений. Таким образом, SHA-0 «сломан» (намного больше, чем SHA-1), и вы не должны его использовать.

Для подписи RSA с SHA-256 вы должны использовать NID_sha256 (для SHA-512, NID_sha512). Если вы используете NID_sha, тогда вы получите неправильную подпись. Внутри процесс подписания включает в себя преобразование, в котором значение хеша (параметры m / m_len в RSA_sign()) дополняется заголовком, который идентифицирует хеш-функцию (поэтому RSA_sign() должен иметь доступ к этой информации через параметр type). Если вы используете NID_sha, тогда этот заголовок скажет: «Это хешированное значение SHA-0 длиной 32 байта», что вдвойне неверно: хеш-значение SHA-0 имеет длину 20 байтов, а не 32; и это не хешированное значение SHA-0, а хешированное значение SHA-256.

Таким образом, ваш подписчик выдает подпись, которая отличается от официального стандарта подписи RSA ( PKCS # 1 ). Таким образом, ваша подпись не подлежит проверке с помощью совместимого верификатора. Однако ваш верификатор также отходит от стандарта тем же способом: используя NID_sha в качестве параметра для RSA_verify(), вы указываете верификатору ожидать заголовок "SHA-0" (и 32 -байтовое значение хеша). Это объясняет, почему вещи работают с вашим кодом: ваш верификатор делает ту же ошибку, что и подписавший, и эти две ошибки удаляются.

Другими словами, вы подписываетесь не с истинным RSA, а с его вариантом, который, на первый взгляд, не менее безопасен, чем подлинная вещь, но все же отличается и поэтому не совместим. Возможно, это не проблема в вашей конкретной ситуации, но, вообще говоря, для криптографических операций вы должны придерживаться буквы стандарта (потому что слабые места в безопасности - это тонкие вещи). Если вы используете NID_sha256 при подписании хеш-значения SHA-256, то вы получите стандартную подпись PKCS # 1 v1.5 RSA, и это намного лучше.

Подводя итог: забудьте NID_sha, используйте NID_sha256, если хэш-значение получено из SHA-256 (NID_sha512 для SHA-512), как для RSA_sign(), так и RSA_verify().

...