在Openssl中NID_sha和NID_sha1之间有什么区别

在Openssl中NID_sha和NID_sha1之间有什么区别,openssl,rsa,digital-signature,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函数对

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是什么

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

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()
)填充一个头,该头标识散列函数(这就是为什么
RSA_-sign()
必须通过其
类型
参数访问此信息的原因)。如果使用
NID_sha
,则此标题将显示“这是一个长度为32字节的sha-0哈希值”,这是双重错误:sha-0哈希值的长度为20字节,而不是32字节;这不是SHA-0散列值,而是SHA-256散列值

因此,基本上您的签名者生成的签名与官方RSA签名标准()不同。因此,您的签名将无法通过兼容验证器进行验证。但是,您的验证器也以相同的方式偏离了标准:通过使用
NID_sha
作为
RSA_verify()
的参数,您可以指示验证器期望一个“sha-0”头(和一个32字节的哈希值)。这就解释了为什么你的代码看起来可以正常工作:你的验证者和你的签名者犯了完全相同的错误,这两个错误相互抵消了

换句话说,您不是使用真正的RSA签名,而是其变体,乍一看,它的安全性不亚于真正的RSA,但仍然不同,因此不可互操作。在您的特定情况下,这可能不是一个问题,但是,一般来说,对于加密操作,您应该遵守标准的文字(因为安全弱点是微妙的)。如果在对SHA-256散列值进行签名时使用
NID_sha256
,则会得到符合标准的PKCS#1 v1.5 RSA签名,这会更好


总而言之:忘记
NID_-sha
,如果哈希值来自sha-256(
NID_-sha512
,对于sha-512),则使用
NID_-sha256
,这两种方法都适用于
RSA\u-sign()
RSA\u-verify()
,非常感谢!这是一个非常乐观的回答。