【问题标题】:M2crypto signature "algorithm"M2crypto 签名“算法”
【发布时间】:2011-04-14 12:16:32
【问题描述】:

这两个代码提供相同的签名,这是预期的:

代码1:

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)

代码2:

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

你能解释一下吗?后一种签名方式有什么问题?

【问题讨论】:

标签: python digital-signature m2crypto


【解决方案1】:

我认为区别在于RSA_sign 对摘要 PKCS1 algorithmIdentifier 和摘要数据进行签名,而RSA_private_encrypt 仅对摘要数据进行签名。

来自 RSA_private_encrypt 手册页:

RSA_PKCS1_PADDING
    PKCS #1 v1.5 padding. This function does not handle the
    algorithmIdentifier specified in PKCS #1. When generating or
    verifying PKCS #1 signatures, RSA_sign(3) and RSA_verify(3) should
    be used.

【讨论】:

  • 谢谢!这当然是有道理的。
【解决方案2】:

EVP.sign() 内部发生的情况如下(相对于普通的RSA.sign()):

sha1_hash = hashlib.sha1(MESSAGE).digest()
# Add ASN.1 SHA-1 OID prefix
sha1_asn1_prefix = '3021300906052b0e03021a05000414'.decode('hex')
asn1_hash = sha1_asn1_prefix + sha1_hash
rsa = RSA.load_key(KEY)
# Use PKCS#1 padding
signature = rsa.private_encrypt(asn1_hash, RSA.pkcs1_padding).encode('hex')

请参阅this answer 以获得更详细的说明,查看this gist 以获得完整示例。

但最重要的是应该使用EVP.sign() 代替上面的代码1 - 它在内部做正确的事情。

【讨论】:

    猜你喜欢
    • 2021-02-17
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 2012-02-03
    • 2019-02-23
    相关资源
    最近更新 更多