Question

I know it's possible to read a certificate in Python by using either OpenSSL or M2Crypto, as greatly explained at How can I retrieve the TLS/SSL peer certificate of a remote host using python?, but I'd like to be able to do the same, with a non trusted certificate.

By non trusted, I mean a certificate I (for example) just generated and paster the csr output into my python function.

Here's how I generated the csr :

openssl req -new -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr

And used the output of domain.csr into the code in the S.O. question before.

As expected, this doesn't work. To be quicker, doing the same using Openssl result in the same error :

openssl x509 -text -in Domain.csr -noout

unable to load certificate 139698977908608:error:0906D06C:PEM routines:PEM_read_bio:no start >line:pem_lib.c:703:Expecting: TRUSTED CERTIFICATE

Expecting: TRUSTED CERTIFICATE is the key issue here.

How can I do ?

Thank you for your help !

Update : By searching more, I read that this would work if the PRIVATE KEY was inside the cert (aka pem) from this S.O answer https://stackoverflow.com/a/12312994/330867, but what I'm trying to implement is a system that can extract informations from certificates that come from other people than mine. And I'm pretty sure "other people" won't want to share their private key, so I remain stuck. Any ideas ?

Update 2: It appears that there is a difference between x509 and req certificates. The one generated with the command before is a req, as stated.

So now I now I can read a x509 certificate with the first SO link, but how can I read a req certificate in python ?

Was it helpful?

Solution

Ok I found my answer and I believe it will help others !

So, there is an important difference between a "req" certificate and a x509 certificate!

In the x509, the Private Key is also included in the file !

So, in the following, I'll show how to generate a certificate and read it in Python, using REQ and x509 type of certificate.

Using a "req" certificate :

To generate it :

openssl req -new -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr

And to read it :

import OpenSSL
# cert contains the content of domain.csr
OpenSSL.crypto.load_certificate_request(OpenSSL.crypto.FILETYPE_PEM, cert).get_subject().get_components()

Using a "x509" certificate :

To generate it :

openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem

And to read it :

import OpenSSL
# cert contains the content of cert.pem
OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert).get_subject().get_components()

That's it !

The difference is located in how you load the certificate in OpenSSL.crypto :

  • For "req" : load_certificate_request()
  • For "x509" : load_certificate()

It was that simple ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top