Lelouch Lamperouge
Lelouch Lamperouge

Reputation: 8411

extracting public key from certificate and encrypting data

This is for a homework assignment! I get the server's certificate using get_peer_certificate() and the calling dump_certificate to dump the certificate in a variable. The format is PEM and looks right to me.

-----BEGIN CERTIFICATE-----
GIBBERISH................
......................
........................

-----END CERTIFICATE-----

How do I extract the server's public key from this file ('server.pubkey') and encrypt plaintext using RSA algorithm and any python library. At the time of writing this, I am using pyOpenSSL

Upvotes: 4

Views: 16155

Answers (4)

Enis Arik
Enis Arik

Reputation: 677

Note that OpenSSL library is not recommended to be used for those purposes. Instead, cryptography library is pointed. It is maintained and regularly updated.

Assuming you have the certificate in Pem format, the following code block will give you public key in string.

from cryptography import x509
from cryptography.hazmat.primitives import serialization

def read_pub_key_from_cert():
    # Read certificate file.
    with open("tls.crt") as certificate:
        cert = certificate.read()

    # Convert it into bytes.
    cert_in_bytes = bytes(cert, 'utf-8')

    # Create x509 certificate object.
    cert_obj = x509.load_pem_x509_certificate(cert_in_bytes)

    # Create Public key object.
    public_key_obj = cert_obj.public_key()

    # Convert Public key object into Pem format in bytes.
    public_pem = public_key_obj.public_bytes(
                    encoding=serialization.Encoding.PEM,
                    format=serialization.PublicFormat.SubjectPublicKeyInfo
    )
    # Convert Public key into string.
    pub_key_string = public_pem.decode("utf-8")

    return(pub_key_string)

Upvotes: 0

Piotr Siejda
Piotr Siejda

Reputation: 317

from cryptography.x509 import load_pem_x509_certificate

cert_str = b"-----BEGIN CERTIFICATE-----MIIDETCCAfm..."
cert_obj = load_pem_x509_certificate(cert_str)
public_key = cert_obj.public_key()
private_key = cert_obj.private_key()

Source: https://pyjwt.readthedocs.io/en/stable/faq.html

Upvotes: 2

Alexandr Shamatov
Alexandr Shamatov

Reputation: 61

    from OpenSSL import crypto        
    crtObj = crypto.load_certificate(crypto.FILETYPE_ASN1, config.x509_certificate)
    pubKeyObject = crtObj.get_pubkey()
    pubKeyString = crypto.dump_publickey(crypto.FILETYPE_PEM, pubKeyObject)

Upvotes: 6

samplebias
samplebias

Reputation: 37909

I'd recommend using a more broad crypto library such as M2Crypto which has the X509 certificate functions as well as RSA encryption:

from M2Crypto import RSA, X509
data = ssl_sock.getpeercert(1)
# load the certificate into M2Crypto to manipulate it
cert = X509.load_cert_string(data, X509.FORMAT_DER)
pub_key = cert.get_pubkey()
rsa_key = pub_key.get_rsa()
cipher = rsa_key.public_encrypt('plaintext', RSA.pkcs1_padding)

Upvotes: 8

Related Questions