python字符串格式pkcs8 RSA签名

时间:2017-06-20 08:06:05

标签: php python cryptography rsa digital-signature

我需要在我的项目中使用pkcs8私钥,如下例所示,我找不到任何与pkcs8签名相关的库或方法,只有pkcs1可用于Crypto.Signature

我的python代码示例:

from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA

privatekey='''-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOuxJs5RD6s2ECEV
C38Jfj6xBBrcX6W1Qy+GLiXhh+wKj650BPSerQNQI+XPx/+uUemk/dJM3RMm75Di
mXJlp7/5LY11VyKSqS+x6ELIvWz8lo2OhHW6/wU4jiQ1MlburYbn/pRRClGGA8i4
FjHMvMu9/QCNPlNTlf7qJDO6lDVlAgMBAAECgYB0iP76/DGXIgAPm2w3v+Xf8X5q
GZRhRqKVmO6wZDbkisRIKa1ZlitNfA6DzpzA2tw9fgrSNJcKpTHGnYPpgEHUQrcw
t471yuAvzAOBffaqVjIt7vKyL3QnkNfxWenliasacX3olwBpKPrkvG75H2KBe9S0
WKpju1Cm6MebAJ3z8QJBAP8gSx3l9nNTqJcBBmP+TGDcTL9Sif2nBZrU/pWnzzop
HolaFIQTYXPIj8rMoVT/c0gLo1gcdHoSUJTbB0WO7V8CQQDsf9FAWCI3fkWgS/fW
21ApO6B07/388CpNHOTjvfsdlent4yXLL+Guh5apMH4Oq0tkGkEij5YPG1EZSYXi
48+7AkEAiX3m3ZMMMXTZe5/CyOrIUL8I4WbjFP8JJzs4hICuTmLQoScZvWAQeeyR
ibKkE4GjqCUVf6u+Hfd20/ICRjtTswJANCjEh8JoWYDZ7k6S7KoV9eIWs3OyurRl
P/idarUdyxqjKzorvbJjvdBdpBbz1lxlFkDMGMk+OTq3GjKi+rVvvQJAGhBieR2Q
69JNeoOg7J8Xk7evNBJHwtJfRDQXKJpN5YZsKclf6oRaYFEQOM6ThuNoYHISfGKw
UbDoUsPZoQFPtQ==
-----END PRIVATE KEY-----'''

signstr = testdata123

key = RSA.importKey(privatekey) 
h = SHA.new(signstr) 
signer = PKCS1_v1_5.new(key) 
signature = signer.sign(h) 
sign = base64.b64encode(signature) 

上面代码生成的签名与我正在使用的api系统中的公钥不匹配。

对于PHP方面,我能够正确签名。 PHP的工作代码如下:

$private_key= openssl_get_privatekey($private_key);
openssl_sign($signStr,$sign_info,$private_key,OPENSSL_ALGO_MD5);
$sign = base64_encode($sign_info);

非常感谢任何有关如何使用python签署RSA pkcs8格式私钥的建议。

1 个答案:

答案 0 :(得分:0)

哈希算法

当然,它必须是不同的,因为你使用不同的哈希算法。

您的Python代码使用SHA-1,您的PHP代码使用MD5。 PHP中的默认哈希算法OPENSSL_ALGO_SHA1documentation describes

if (!openssl_sign($signStr, $sign_info, $private_key)) {
    echo "Failed to sign";
}

密钥编码

编码私钥的方法有很多种。两种最常见的方式是PKCS#1和PKCS#8编码。查看有关here的更多信息。

密钥编码在这里不是问题,因为pycrypto和openssl都使用正确的编码。

填充

有两个常用的padding schemes用于签名:PKCS#1 v1.5填充和RSA-PSS(技术上是RSASSA-PKCS1-V1_5和RSASSA-PSS)。它们都在PKCS#1中定义,但后者在PKCS#1 v2.x中引入。

Pycrypto支持两种填充方案,但openssl仅支持PHP中的PKCS#1 v1.5。

兼容性

如果要检查不同语言之间相同算法的兼容性,则需要使用私钥登录,并使用公钥验证另一个的签名。完成后,如果您还需要另一个方向,可以尝试相反的方法 这仅适用于RSA-PSS,因为它是随机的。

如果您使用的是未随机化的PKCS#1 v1.5填充,您应该能够在Python和PHP中创建签名并直接比较它们以检查兼容性。