sun*_*nyX 3 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.
Run Code Online (Sandbox Code Playgroud)
但我在Openssl源代码中看到另一种可用的NID_sha类型.有人可以帮我解决这两者之间的区别吗?
我打算使用RSA_Sign函数来签署SHA-256,SHA-512的摘要,但我没有看到SHA-256和SHA-512的相应类型参数,所以在这些情况下我应该为type参数输入什么.
现在我使用类型为NID_sha并尝试签署SHA-256,SHA-512的哈希,并且两者都成功地工作,它提供了正确的签名,后来的签名验证也是正确的,但我只是想知道是什么是NID_sha?
任何帮助将不胜感激.谢谢!
Tho*_*nin 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_lenparameters to RSA_sign())用标题填充,标题用于标识散列函数(这就是为什么RSA_sign()必须通过其type参数访问此信息).如果你使用NID_sha那么这个标题会说"这是一个长度为32字节的SHA-0哈希值",这是双重错误:SHA-0哈希值的长度为20字节,而不是32; 这不是SHA-0散列值,而是SHA-256散列值.
所以基本上你的签名者会产生一个不符合官方RSA签名标准(PKCS#1)的签名.因此,使用兼容验证程序无法验证您的签名.但是,验证程序也会以相同的方式脱离标准:通过使用NID_shaas参数RSA_verify(),指示验证程序期望"SHA-0"标头(以及32字节的散列值).这解释了为什么事情似乎与您的代码一起使用:您的验证程序与您的签名者完全相同,并且两个错误被取消.
换句话说,你并没有使用真正的RSA签名,而是使用它的变体,乍一看,它的安全性并不比真正的RSA强,但仍然不同,因此不能互操作.也许这不是你特定情况下的问题,但一般来说,对于加密操作,你应该坚持标准的字母(因为安全漏洞是微妙的事情).如果您NID_sha256在签署SHA-256哈希值时使用,那么您将获得符合标准的PKCS#1 v1.5 RSA签名,这要好得多.
总结一下:忘了NID_sha,NID_sha256如果哈希值来自SHA-256(NID_sha512对于SHA-512),请使用RSA_sign()和RSA_verify().