Getting public key BIT STRING in python

41 views Asked by At

I have a PEM encoded certificate. I want to get the ASN.1 BIT STRING of the public key. I am using pyca's cryptography package. All I am getting is the whole subject public key info in DER format. My question is is there any easy way to get only the public key's BIT STRING? Mainly, I want to calculate the issuerKeyHash which is needed to build OCSP request.

Input:

from cryptography import x509
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat

with open ("test_issuer.pem","rb") as file:
    pem_data = file.read()
    issuer_cert = x509.load_pem_x509_certificate(pem_data)

pubkey = issuer_cert.public_key()
pubkey_bytes = pubkey.public_bytes(encoding=Encoding.DER, format=PublicFormat.SubjectPublicKeyInfo)
print(pubkey_bytes.hex())

Output:

3059301306072a8648ce3d020106082a8648ce3d030107034200041306605a1910efd18b382f05719062bea9c63a118124bc3cde6a4959734ecef00129c92573255bca278f5a5f3e403128bd9b9ad9d5517c4f796120e673a9aa9e

As mentioned, this is the whole subject public key info (91 bytes). Using an ASN.1 viewer or openssl, I observed that the actual BIT STRING excluding all the algorithm info, tags and length starts from byte 25. I can of course write a function to read all the tags and length info and extract the BIT STRING. But is there any built in function for this purpose?

Expected output:

041306605a1910efd18b382f05719062bea9c63a118124bc3cde6a4959734ecef00129c92573255bca278f5a5f3e403128bd9b9ad9d5517c4f796120e673a9aa9e
1

There are 1 answers

0
Topaco On BEST ANSWER

The output you expect is the hex encoded public key in uncompressed format. To obtain the uncompressed format, only the encoding and format specification must be changed:

from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
...
pubkey_bytes = pubkey.public_bytes(encoding=Encoding.X962, format=PublicFormat.UncompressedPoint)
print(pubkey_bytes.hex()) # 041306605a1910efd18b382f05719062bea9c63a118124bc3cde6a4959734ecef00129c92573255bca278f5a5f3e403128bd9b9ad9d5517c4f796120e673a9aa9e