什么是Openssl中NID_sha和NID_sha1之间的区别

时间:2011-04-07 06:11:20

标签: openssl rsa digital-signature

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.

但我在Openssl源代码中看到另一种可用的NID_sha类型。 有人可以帮助我解决这两者之间的区别吗?

我打算使用RSA_Sign函数来签署SHA-256,SHA-512的摘要,但我没有看到SHA-256和SHA-512的相应类型参数,那么我应该为这些类型参数输入什么例。

现在我使用类型为NID_sha并尝试签署SHA-256,SHA-512的哈希,并且两者都成功地工作,它提供了正确的签名,后来的签名验证也是正确的, 但我只是想知道什么是NID_sha?

任何帮助将不胜感激。 谢谢!

1 个答案:

答案 0 :(得分:11)

NID_sha指定SHA-0,它是SHA-1的直接祖先。 SHA-0最初被称为“SHA”,但很快就发布了一个名为SHA-1的修改版本;之前的“SHA”被宣布为过时,现在传统上称为“SHA-0”。改变的实际原因并未正式,但人们普遍认为SHA-0存在某种弱点 - 几年后由独立研究人员发现,并用于产生碰撞。因此,SHA-0被“破坏”(远远超过SHA-1),你不应该使用它。

对于使用SHA-256进行RSA签名,您应该使用NID_sha256(对于SHA-512,NID_sha512)。如果您使用NID_sha,则会收到错误的签名。在内部,签名过程包括一个转换,其中散列值(m / m_len参数到RSA_sign())用标头填充,标识散列函数(这就是为什么{{1必须通过其RSA_sign()参数访问此信息。如果你使用type,那么这个标题会说“这是一个长度为32字节的SHA-0哈希值”,这是双重错误:SHA-0哈希值的长度为20字节,而不是32;这不是SHA-0散列值,而是SHA-256散列值。

所以基本上你的签名者会产生一个不符合官方RSA签名标准(PKCS#1)的签名。因此,使用兼容验证程序无法验证您的签名。但是,您的验证程序以相同的方式偏离标准:通过使用NID_sha作为NID_sha的参数,您指示验证程序期望“SHA-0”标头(和32字节的哈希值)。这解释了为什么事情似乎与您的代码一起使用:您的验证程序与您的签名者完全相同,并且两个错误被取消。

换句话说,你没有使用真正的RSA签名,而是使用其中的一个变体,乍一看,它不比真正的RSA安全,但仍然不同,因此不能互操作。也许这不是你特定情况下的问题,但一般来说,对于加密操作,你应该坚持标准的字母(因为安全漏洞是微妙的事情)。如果在签署SHA-256哈希值时使用RSA_verify(),那么您将获得符合标准的PKCS#1 v1.5 RSA签名,这样会更好。

总结:忘记NID_sha256,如果哈希值来自SHA-256(SHA-512为NID_sha),请使用NID_sha256 NID_sha512RSA_sign() {1}}。