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?
任何帮助将不胜感激。 谢谢!
答案 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_sha512
和RSA_sign()
{1}}。