我对安全性没有多少体验,但现在我必须在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
?
答案 0 :(得分:3)
您的证书不包含私钥。
从我在您的C#代码中看到的内容,我猜测您是从Windows证书存储区获取证书的。此商店可以包含附加和不附加私钥的证书。
另一方面, .cer
个文件(通常)不包含私钥 - 它们只有公钥。这就是为什么不能签名的原因。
我猜测您已从Windows证书存储区导出.cer
文件,但未选择"导出私钥"选项。您应该以{{1}}或.pfx
格式重新导出,以获得更好的运气,并尝试使用该文件进行签名。