Python print all public key certificate information (X.509 Format) - python-3.x

I am trying to write a Python3 program which will show me all information which is included in a public key certificate, similar to the following linux command:
openssl x509 -in website.com.pem -text
which will return a result similar to
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
04:7a:f7:95:47:c0:7d:0f:ef:80:a5:b2:1f:51:e3:63
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
Validity
Not Before: Mar 12 00:00:00 2018 GMT
Not After : Mar 11 23:59:59 2020 GMT
Subject: OU = Domain Control Validated, OU = PositiveSSL, CN = acs.cdroutertest.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
as shown on the following website: https://support.qacafe.com/knowledge-base/how-do-i-display-the-contents-of-a-ssl-certificate/
I was trying the Cryptography or pyopenssl modules in python3 already, and was able to import the certificate and display e.g. the public key. However i did not find a way to go through all information available and just display them, without having to write a print() statement for every field that might or might not be available in the certificate.
Does anybody have an idea how to push me into the right direction?
Its appreciated, thank you!

A solution that has actually slipped my attention is the use of the module asn1tools
import asn1tools
foo = asn1tools.compile_files("x509.asn")
output = foo.decode("Certificate", cert)
Only all ASN.1 definitions needed for X509 have to be available in the file x509.asn (available via the respective RFC), while "cert" holds the bytestring.
The result will be a python dict with all the information contained, without having to loop through anything or missing some unusual parameters

Related

Store RSA keys in Airflow Connectors

What is the best way to store RSA connectors in Airflow Connectors?
hook = BaseHook.get_connection("my_rsa")
key = hook.extra
I am using this way. However, the key is stored as String. What is the best way to convert this to bytes?
It sounds like you're trying to secure RSA Keys... you should use airflow's crypto module
You can encrypt your keys and keep the encrypted key in an environment variable or in your own airflow.cfg
Do note that Airflow doesn't handle key rotation by default for you.
from the docs
Install crypto package pip install apache-airflow[crypto]
Generate fernet_key, using this code snippet below. fernet_key must be a base64-encoded 32-byte key:
from cryptography.fernet import Fernet
fernet_key=Fernet.generate_key()
print(fernet_key.decode()) # your fernet_key,keep it in secured place!
Replace airflow.cfg fernet_key value with the one from above. Alternatively, you can store your fernet_key in OS environment variable - You do not need to change airflow.cfg in this case as Airflow will use environment variable over the value in airflow.cfg:
#Note the double underscores
export AIRFLOW__CORE__FERNET_KEY=your_fernet_key

Google cloud storage signed url how to generate sha256 hash in python 3?

I need to use python3 and google cloud storage tgt. The example codes here is written in python2 and I am trying to change the script so it works in python3.
In python 2, SHA256 works fine.
import Crypto.Hash.SHA256 as SHA256
def _Base64Sign(self, plaintext):
"""Signs and returns a base64-encoded SHA256 digest."""
shahash = SHA256.new(plaintext)
but in python3, it doesn't seem to generate the same key.
import Crypto.Hash.SHA256 as SHA256
def _Base64Sign(self, plaintext):
"""Signs and returns a base64-encoded SHA256 digest."""
t = plaintext.encode()
shahash = SHA256.new(t)
#print(shahash)
signer = PKCS1_v1_5.new(self.key)
signature_bytes = signer.sign(shahash)
return base64.b64encode(signature_bytes)
So my question is if plaintext.encode() is changing sha256 hash or it's just pycrypto has changed for python3. What can I do to generate the same key as python 2 version? Do I have to port python2 in python 3?
Any advice would be appreciated, thanks.

Importing RSA Key Pair from remote Machine

I'm fairly new to python but have basic understanding of crypto modules. However, I'm trying to import an RSA key pair from a remote machine(i.e. Safenet) to run some performance tests on signing data. I'm building the framework in Python and I haven't found many clear examples. For instance:
from Crypto.PublicKey import RSA
f = open('path/to/pair/00000103000003A2','r')
r = RSA.importKey(f.read(), passphrase='123456') # Index out of range error
print(r)
This is about as far as I'm getting with opening the key pair. I can import the key pair to my personal computer so it's in a directory I have access to.
I have found the answer elsewhere.
from OpenSSL import crypto
passwd = 'The password of your created .p12 file'
p12 = crypto.load_pkcs12(open("Path to p12 file.p12 ",'rb').read(),passwd)
print(p12.get_certificate()) #Prints object location
print(p12.get_privatekey()) #Prints object location
p12.get_ca_certificates()
Here's a link to convert object location to PEM formatted strings. PyOpenSSL convert certificate object to .pem file

How to generate a self-signed certificate for use with Network.TLS

I am writing a program to run on a single server that I control, that accepts connections from clients. The data needs to be encrypted, and server authentication is a nice touch. I'm planning to use the tls package from Hackage, as it provides both client and server encryption functionality.
I'm trying to generate a key and convert it to the X509 type, needed for the pCertificates parameter to Network.TLS. I generated the key using GnuTLS's certtool, following the directions under "Self-signed certificate generation":
certtool --generate-privkey --outfile ca-key.pem
certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca-cert.pem
Here is the program I'm using to try to decode the X509 file:
import Data.ByteString (ByteString)
import Data.Certificate.PEM
import Data.Certificate.X509
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
decode :: ByteString -> Either String X509
decode pem =
case parsePEMCert pem of
Nothing -> Left "certificate not in PEM format"
Just certdata -> decodeCertificate $ L.fromChunks [certdata]
main :: IO ()
main = print . decode =<< B.readFile "ca-cert.pem"
It parses the PEM wrapper successfully, but does not recognize the data within:
$ ./decode
Left "certificate error: \"subject public key bad format : [OID [1,2,840,113549,1,1,1]]\""
Is this a bug in the tls package? Or am I not generating the right type of file by using the certtool commands above?
Community-wiki answer with two solutions from the comments.
1) It worked when I used GnuTLS 3.0.4 instead.
2) For future references, we worked around the issue by generating the certificate with OpenSSL toolchain, which seems to be better supported by the tls package.

How to verify a signature using M2Crypto 0.16

After some goggling I found some usual answers for this question, like:
How to load an RSA key from a PEM file and use it in python-crypto
some code:
x509 = X509.load_cert_string(certificate)
pubkey = x509.get_pubkey()
pubkey.reset_context(md=sha1)
pubkey.verify_init()
pubkey.verify_update(content)
decoded_signature = signature.decode('base64')
if pubkey.verify_final(decoded_signature)==0:
print 'error'
sys.exit(1)
and the code presented above works fine in M2Crypto 0.20.
But I need to do exactly the same think using the M2Crypto 0.16 (the official package in RHEL5), and I have problems using the pubkey.verify_final method because in this particular version the signature parameter doesn't exist.
So how can I do it? using the M2Crypto 0.16
Thanks.
Lucky for you, the OpenSSL function you need is available in M2Crypto 0.16, it is just the Python method that is not providing the extra argument you need. This is easy to work around. Where you would call pubkey.verify_final(decoded_signature), call pubkey_verify_final(pubkey, decoded_signature), which you will define in your code as:
from M2Crypto import m2
def pubkey_verify_final(pubkey, decoded_signature):
return m2.verify_final(pubkey.ctx, decoded_signature, pubkey.pkey)
(Note, I did not actually test that, just compared the source between 0.16 and 0.20.)

Resources