Greg Eremeev
Greg Eremeev

Reputation: 1840

How to check for Python, the key associated with the certificate or not

I know that the blocks modulus in the certificate and private key must be the same if they are related. But how this can be checked by using Python? I am looking for a solution to the OpenSSL library, but I found none. Please tell me the solution, how to understand what the certificate and private key associated with using Python. If the private key is not encrypted in the format PEM, a certificate in PEM format. Preferably using standard libraries. Without using OpenSSL through the subprocess
Thanks.

Upvotes: 1

Views: 11286

Answers (3)

ubered_scientist
ubered_scientist

Reputation: 71

I don't have a solution without using some SSL library, but if you want a pure pyopenssl solution, you can try this:

from OpenSSL.crypto import load_certificate, load_privatekey, dump_publickey, FILETYPE_PEM

def compare_cert(cert_str, key_str):
    cert = load_certificate(FILETYPE_PEM, crt)
    key = load_privatekey(FILETYPE_PEM, key)
    cert_pub = dump_publickey(FILETYPE_PEM, cert.get_pubkey())
    key_pub= dump_publickey(FILETYPE_PEM, key)
    if cert_pub != key_pub:
        print('Error, certificate key does not match provided key')

Not sure when dump_publickey was added but it seems to work well. I only know this works on python3 with pyopenssl=19.1.0

Upvotes: 2

ConConovaloff
ConConovaloff

Reputation: 141

def check_associate_cert_with_private_key(cert, private_key):
    """
    :type cert: str
    :type private_key: str
    :rtype: bool
    """
    try:
        private_key_obj = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, private_key)
    except OpenSSL.crypto.Error:
        raise Exception('private key is not correct: %s' % private_key)

    try:
        cert_obj = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
    except OpenSSL.crypto.Error:
        raise Exception('certificate is not correct: %s' % cert)

    context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
    context.use_privatekey(private_key_obj)
    context.use_certificate(cert_obj)
    try:
        context.check_privatekey()
        return True
    except OpenSSL.SSL.Error:
        return False

source: http://docs.ganeti.org/ganeti/2.14/html/design-x509-ca.html#verify-whether-x509-certificate-matches-private-key

Upvotes: 10

Camille G.
Camille G.

Reputation: 3256

There is a Python interface to the OpenSSL library : pyOpenSSL currently in version 0.13.1.

EDIT : The answer to the question...

Verify that a private key matches a certificate with PyOpenSSL :

import OpenSSL.crypto
from Crypto.Util import asn1

c=OpenSSL.crypto

# The certificate - an X509 object
cert=...

# The private key - a PKey object
priv=...

pub=cert.get_pubkey()

# Only works for RSA (I think)
if pub.type()!=c.TYPE_RSA or priv.type()!=c.TYPE_RSA:
    raise Exception('Can only handle RSA keys')

# This seems to work with public as well
pub_asn1=c.dump_privatekey(c.FILETYPE_ASN1, pub)
priv_asn1=c.dump_privatekey(c.FILETYPE_ASN1, priv)

# Decode DER
pub_der=asn1.DerSequence()
pub_der.decode(pub_asn1)
priv_der=asn1.DerSequence()
priv_der.decode(priv_asn1)

# Get the modulus
pub_modulus=pub_der[1]
priv_modulus=priv_der[1]

if pub_modulus==priv_modulus:
    print('Match')
else:
    print('Oops')

(Source : http://www.v13.gr/blog/?p=325)

Upvotes: 4

Related Questions