无法在 python 中使用 X509Certificate 对数据进行签名

Posted

技术标签:

【中文标题】无法在 python 中使用 X509Certificate 对数据进行签名【英文标题】:Unable to sign data with X509Certificate in python 【发布时间】:2014-01-25 06:36:33 【问题描述】:

我在安全方面没有太多经验,但现在我必须在 python 中实现一个签名程序。

我有一个证书somename.cer。我有一个c# 实现示例,说明如何使用该字符串对我的字符串进行签名,如下所示:

CertColl 是证书的集合,相关代码在前几行中找到带有Thumbprint 的相关证书并返回证书列表。

X509Certificate2 cert = certColl[0]
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
return Convert.ToBase64String(rsa.SignData(Encoding.GetEncoding(1251).GetBytes(my_string), new SHA1CryptoServiceProvider()));

my_string是要在代码中签名和构造的字符串,但我不需要在此处添加这些步骤

所以我试图在this previous Q&A 的帮助下在 Python 中实现这一点

from Crypto.Util.asn1 import DerSequence
from Crypto.PublicKey import RSA
from binascii import a2b_base64

pem = open("some-path/somefile.cer")  # I have a certificate with `cer` extension
lines = pem.replace(" ",'').split()
der = a2b_base64(''.join(lines[1:-1]))

cert = DerSequence()
cert.decode(der)
tbsCertificate = DerSequence()
tbsCertificate.decode(cert[0])
subjectPublicKeyInfo = tbsCertificate[6]

rsa_key = RSA.importKey(subjectPublicKeyInfo)

正如我所料,现在我可以用这个签名my_string

rsa_key.sign("Hello World", "")

但我收到以下错误:

TypeError:此对象中的私钥不可用

我是不是做错了什么,比如用错误的方法在 python 中模仿rsa.SignData

【问题讨论】:

【参考方案1】:

您的证书不包含私钥。

根据我在您的 C# 代码中看到的内容,我猜您是从 Windows 证书商店获取证书。这个存储可以包含带有和不带有私钥的证书。

.cer 文件,另一方面,(通常)不包含私钥 - 它们只有公钥。这就是为什么用它签名是不可能的。

我猜您已经从 Windows 证书存储中导出了 .cer 文件,并且没有选择“导出私钥”选项。以.pfx.pvk 格式重新导出它并尝试使用该文件签名,您应该会获得更好的运气。

See more on this topic here

【讨论】:

以上是关于无法在 python 中使用 X509Certificate 对数据进行签名的主要内容,如果未能解决你的问题,请参考以下文章

如何从 python 中的 x509 证书中提取公钥?

无法使用带有 X509 用户的 mongoose 连接到 Mongo DB

httpclient4.4信任所有请求支持https

如何在 PyCrypto 中使用 X509 证书?

无法将密钥文件添加到 X509Certificate2

OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certif