M2加密签名“算法”
这两个代码提供了相同的签名,这是预期的:
code1:
from M2Crypto import RSA, EVP
import base64, hashlib
text = "some text"
pkey = EVP.load_key("mykey.pem") #"mykey.pem" was generated as: openssl genrsa -des3 -out mykey.pem 2048
pkey.sign_init()
pkey.sign_update(text)
signature = pkey.sign_final()
print base64.b64encode(signature)
code2:
pkey = RSA.load_key("mykey.pem")
signature = pkey.sign(hashlib.sha1(text).digest())
print base64.b64encode(signature)
但是,如果我想“模仿”签名算法,即用私钥加密摘要,我会得到不同的签名,即:
pkey = RSA.load_key("mykey.pem")
signature = pkey.private_encrypt(hashlib.sha1(text).digest(), RSA.pkcs1_padding)
print base64.b64encode(signature) #different from the two above
您能否提供一些解释?后一种签名方式有什么问题吗?
These two codes provide the same signature, which is expected:
code1:
from M2Crypto import RSA, EVP
import base64, hashlib
text = "some text"
pkey = EVP.load_key("mykey.pem") #"mykey.pem" was generated as: openssl genrsa -des3 -out mykey.pem 2048
pkey.sign_init()
pkey.sign_update(text)
signature = pkey.sign_final()
print base64.b64encode(signature)
code2:
pkey = RSA.load_key("mykey.pem")
signature = pkey.sign(hashlib.sha1(text).digest())
print base64.b64encode(signature)
However, if I want to "imitate" the signature algorithm, i.e. encrypting the digest with the private key, I get a different signature, i.e.:
pkey = RSA.load_key("mykey.pem")
signature = pkey.private_encrypt(hashlib.sha1(text).digest(), RSA.pkcs1_padding)
print base64.b64encode(signature) #different from the two above
Could you please provide some explanation? What is wrong with the latter way of signing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为不同之处在于,
RSA_sign
将摘要 PKCS1 算法标识符与摘要数据一起签名,其中RSA_private_encrypt
仅对摘要数据进行签名。从 RSA_private_encrypt 手册页:
I believe the difference is that
RSA_sign
signs the digest PKCS1 algorithmIdentifier along with the digest data, whereRSA_private_encrypt
signs only the digest data.From the RSA_private_encrypt man page:
EVP.sign()
内部发生的情况如下(与普通的RSA.sign()
相反):请参阅 这个答案以获得更详细的解释和这个要点 获取完整示例。
但底线是应该使用
EVP.sign()
来代替上面的代码 1 - 它在内部做了正确的事情。What happens internally in
EVP.sign()
is as follows (as opposed to plainRSA.sign()
):See this answer for longer explanation and this gist for a full example.
But the bottom line is that
EVP.sign()
should be used instead as in code 1 above - it does the right thing internally.