В чем разница между NID_sha и NID_sha1 в Openssl

#openssl #rsa #digital-signature

#openssl #rsa #цифровая подпись

Вопрос:

Страница руководства для 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:

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, то вы получаете соответствующую стандарту RSA-подпись PKCS # 1 версии v1.5, и это намного лучше.

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

Комментарии:

1. Большое вам спасибо! Ответ в значительной степени в яблочко.