pstatix
pstatix

Reputation: 3858

Verifying private key belongs to certificate with pyca

I have a private key and a certificate in PEM format and I would like to verify that the two items are associated. A solution would be similar to this answer for PyOpenSSL but using the cryptography module.

What I have is the following:

from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

crt = '/path/to/crt'
key = '/path/to/privatekey'

cert = load_pem_x509_certificate(open(crt, 'rb').read(), default_backend())
prikey = serialization.load_pem_private_key(open(key, 'rb').read(), password=None, default_backend())

The crt and key files were created from a single .p12, so the association is known to be valid, but I am in search of a programmatic way to verify that should such an association be unknown. The result should raise an exception or return True/False indicating the private key is not associated with the certificate.

EDIT: So I was able to work out how to extract the keys as strings which I could compare doing the following:

cpub = cert.public_key().public_bytes(serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo)
pkpub = prikey.public_key().public_bytes(serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo)

print(cpub == pkpub) # True

However I'd like to know if there is a way to verify this using their interfaces rather than bytestring comparisons; obviously they match by sharing the same public key since an RSA private key contains the public key; this just seems flimsy to verify.

Upvotes: 0

Views: 1976

Answers (1)

Bram
Bram

Reputation: 3273

A certificate has a signature which can be verified using the public key of the private key that signed the certificate (the private key in your .p12 file).

from cryptography.hazmat.primitives.asymmetric import padding

prikey.public_key().verify(
    cert.signature,
    cert.tbs_certificate_bytes,
    # Depends on the algorithm used to create the certificate
    padding.PKCS1v15(),
    cert.signature_hash_algorithm,
)

Upvotes: 3

Related Questions