2017-07-26 51 views
1

我正在将服务从Python 2.7迁移到使用RSA加密/解密与另一服务进行通信的Python 3.5。RSA签名不同于rsa模块和m2crypto生成


的Python(V2.7)m2crypto(0.25.1)<正确的签名>

key = M2Crypto.RSA.load_key(private_key) 
digest = hashlib.sha1(bytes(cipher_text, encoding="UTF-8")).hexdigest() 
signature = hexlify(key.private_encrypt(digest, M2Crypto.RSA.pkcs1_padding)) 

的Python(V3.5)RSA(v3.4.2)

pri_key = rsa.PrivateKey.load_pkcs1(private_key) 
signature = hexlify(rsa.sign(cipher_text.encode(), pri_key, "SHA-1")) 

以上代码产生的签名是不同的。这些软件包有什么区别?

回答

0

您正在执行不同的加密操作。 加密与私钥!=数字签名

signature = hexlify(key.private_encrypt(digest, M2Crypto.RSA.pkcs1_padding)) 

signature = hexlify(rsa.sign(cipher_text.encode(), pri_key, "SHA-1")) 

与PCKS#1 V1.5的数字签名,使上摘要算法标识符和所述消息的编码的摘要的RSA加密在ASN.1

signature = 
    RSA_Encryption( 
     ASN.1(DigestAlgorithmIdentifier + SHA1(message))) 

虽然加密不包括摘要算法标识符

似乎Python的key.private_encrypt是OpenSSL的RSA_private_encrypt包装看一看,以警告有关pkcs1_padding您使用

RSA_PKCS1_PADDING

PKCS#1 v1.5的填充。此功能不处理在PKCS#1中指定的algorithmIdentifier。在生成或验证PKCS#1签名时,应使用RSA_sign(3)RSA_verify(3)

对于数字签名,您应该使用sign而不是private_encrypt。但是,如果您想要加密来隐藏邮件的内容,则应该使用公钥加密,而不是私钥。

+0

但是如果第二个服务接受从m2crypto代码生成的签名会怎么样?在那种情况下我应该怎么做? – infiQuanta

+0

如果你拥有这项服务,我建议你相应地修改它。如果这是不可能的,我想你别无选择,只能继续使用'private_encrypt' – pedrofb

+1

替代选项是帮助我完成https://gitlab.com/m2crypto/m2crypto/merge_requests/65并且您不必移植出M2Crypto;)。不过,我现在正在为OpenSSL 1.1.0提供支持,因此预计该分支机构的主要重组。 – mcepl