Mp0int
Mp0int

Reputation: 18737

Unable to sign data with X509Certificate in python

I do not have much experiance with security, but now I have to implement a signature procedure in python.

I have a certificate somename.cer. I have an c# implementation example of how to sign my string with that string as follows:

CertColl is the collection of certificates where related code finds the related certificate with Thumbprint in the previous lines and returns a list of certificates.

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

my_string is the string to be signed and constructed within the code, but I do not need to add those steps in here

So I am trying to implement this in Python with the help of this previous Q&A

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)

As I expect, now I can sign my_string with this.

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

But I receive the following error:

TypeError: Private key not available in this object

Am I doing something wrong, like usnig the wrong method to mimic rsa.SignData in python?

Upvotes: 4

Views: 2081

Answers (1)

DarkWanderer
DarkWanderer

Reputation: 8866

Your certificate does not contain the private key.

From what I see in your C# code, I'm guessing you're sourcing the certificate from the Windows Certificate Store. This store can contain certificates both with and without private key attached.

.cer files, on the other hand, (usually) don't contain private keys - they only have public keys. That's why signing with it is impossible.

I'm guessing you have exported the .cer file from the Windows Certificate Store and haven't selected the "Export private key" option. You should have better luck by re-exporting it in .pfx or .pvk format and try signing with that file.

See more on this topic here

Upvotes: 3

Related Questions