I'm tring to create python script, that would take PKCS#12 package and print some information contained in x509 certificate and using for this purpouses PyOpenSSL module. So far i want to fetch from certificate public key. But PKey object doesn't have appropriate method. Where can I move out of here ? Any ideas how to get public key ?
pfx=open('./1.p12','rb').read()
PKCS=crypto.load_pkcs12(pfx)
cert=PKCS.get_certificate()
PKey=cert.get_pubkey()
print PKey
<OpenSSL.crypto.PKey object at 0x012432D8>
Thanks.
First you can load the certificate like this
from OpenSSL import crypto
#cert is the encrypted certificate int this format -----BEGIN -----END
crtObj = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
pubKeyObject = crtObj.get_pubkey()
pubKeyString = crypto.dump_publickey(crypto.FILETYPE_PEM,pubKeyObject)
print pubKeyString
you will see something like
-----BEGIN PUBLIC KEY-----
....
....
-----END PUBLIC KEY-----
I am assuming you want to read the public key from the file.
First install pyopenssl
pip install pyopenssl
from OpenSSL import crypto
import os
file_path = os.path.join(os.getcwd(), '/certificates/test.crt')
with open(file_path, "r") as f:
cert = f.read()
pub_key_obj = crypto.load_certificate(crypto.FILETYPE_PEM, cert).get_pubkey()
pub_key = crypto.dump_publickey(crypto.FILETYPE_PEM, pub_key_obj)
print(pub_key)
or
file_path = '~/.ssh/private_key'
with open(file_path, "rb") as f:
raw = f.read()
private_key_obj = crypto.load_privatekey(crypto.FILETYPE_PEM, raw)
pub_key = crypto.dump_publickey(crypto.FILETYPE_PEM, private_key_obj)
print(pub_key)
You will get output as:
-----BEGIN PUBLIC KEY-----
....
-----END PUBLIC KEY-----
Would this work?
print PKey
<OpenSSL.crypto.PKey object at 0x012432D8>
from OpenSSL import crypto
crypto.dump_privatekey(PKey)
Instead use:
c.dump_privatekey(c.FILETYPE_TEXT,pubkey)
Related
In pyOpenSSL i haven't been able to find a way to encrypt a RSA private key with AES 256 just yet, been looking all over the place for this but cant seem to find a way.
Before i used OpenSSL to get the key and ca/cl certificates but now im opting to make an application where i need to handle the pfx-file in certain ways.
In OpenSSL i used to do the following:
openssl pkcs12 -in file.pfx -nocerts -out key.key
after that i did:
openssl rsa -aes256 -key.key -out encrypted.key
is there anything similar in pyOpenSSL using crypto?
I believe I solved this. But for anyone wondering, this is what I did:
import os
import shutil
from Crypto.PublicKey import RSA
def encrypt(old_key, new_key, passphrase):
key = RSA.importKey(open(old_key, 'rb').read())
with open(new_key, 'wb') as f:
pem_key = key.export_key(format='PEM', passphrase=passphrase, pkcs=8, protection='PBKDF2WithHMAC-SHA1AndAES256-CBC')
f.write(pem_key)
f.close()
if os.path.exists(old_key):
os.remove(old_key)
encryptAES('path_to_old_key', 'path_to_new:key.key', 'supersecretpassword')
One question still remaining is if there's anyway to output the encryption info done in python similar to OpenSSL?
If you run openssl rsa -aes256 -in old.key -out new.key
The key will return attributes in the beginning like such:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC
Key here...
-----END RSA PRIVATE KEY-----
However when I export the private key in Python I just get:
-----BEGIN ENCRYPTED PRIVATE KEY-----
Key here...
-----END ENCRYPTED PRIVATE KEY-----
Is there anyway to display these attributes with pycryptodome?
I generated a self-siged certificate like so:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
The file cert.pem contains my public key. I wish to extract this public key from this file.
The way I tried to do is:
f = open('cert.pem', "rb")
pem_data = f.read()
f.close()
print(pem_data)
key = serialization.load_pem_public_key(pem_data, backend=default_backend())
However, after running the code, I get this error:
ValueError: Could not deserialize key data.
As a result I unable to extract the public key.
How do I fix this in order to extract the public key?
Note in the document
A PEM block which starts with -----BEGIN CERTIFICATE----- is not a public or private key, it’s an X.509 Certificate. You can load it using load_pem_x509_certificate() and extract the public key with Certificate.public_key.
Just try this:
from cryptography.hazmat.backends import default_backend
from cryptography import x509
f = open('cert.pem', "rb")
pem_data = f.read()
f.close()
key = x509.load_pem_x509_certificate(pem_data, backend=default_backend())
public_key = key.public_key()
In the first place check cryptography library is installed if it's no like that so:
pip install cryptography
You have to create your RSA keys with OpenSSL:
openssl genrsa -out jwt-key 4096
openssl rsa -in jwt-key -pubout > jwt-key.pub
reference : enter link description here
I am having difficulties debugging a django/python application that requires a public key to be used to sign a certificate.
1. I created a key in PEM format from my private key using the following command
openssl rsa -pubout -in ~/.ssh/id_rsa > samplePEMKey.pub
The key is given below
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8K/LfOBi+QrINSseqWwc
JGo4uE49Dc42zF2Jwbmc6iXIln8AWX5M+yn15dYOXzbHGbopH8bpF9CsJ/DPHg87
D1At1XwAy5aR5w7pXE//5p/saW50Sm/eY6Nugs9hgAXUTcMMAEXCIG17dLoUzhwE
YdzuPm350h39bTmI7Fz95koTbsKJUi+6337GJ3cWKxMBkEmWvpGo4Nko01xtEnUZ
GweKexr1roE8jZPpzuNeUy+S5tvH5emyBIBdroBVxBtz1OUIoP0oAOrQ5RtRPAcT
TsSWjMtyF2gO5GxeMErRqnLAtWJs4QlaJacVnMMTAgRjrGkUZdsqngM/fjQXfeZV
SwIDAQAB
-----END PUBLIC KEY-----
In my python app I am using OpenSSL and trying to load the key using
pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, samplePEMKey)
When running the django app I get the following error at the above line.
Request Method: POST
Request URL: http://127.0.0.1:8000/snapshotuploader/single/
Django Version: 1.3.1
Exception Type: Error
Exception Value:
[('PEM routines', 'PEM_read_bio', 'no start line')]
Here's how I read the public key from the file
file_path = '/home/XXXX/co/certserver/LicenseServer/home_folder/dldl/samplePEMKey.pub'
try:
fin = open(file_path, 'r')
except IOError:
return HttpResponse('IO Error opening uploaded file.')
try:
samplePEMKey = fin.read()
fin.close()
except IOError:
return HttpResponse('IO Error reading uploaded file.')
Appreciate any help in solving this issue. Thanks in advance.
Took a while to spot it, but you are trying to read a public key with a private key method. If you want to use load_privatekey you should use the original id_rsa as input.
I don't remember how to do the same with OpenSSL.crypto, but at least with the pycrypto toolkit's RSA implementation your sample key imports just fine:
>>> kt = open("samplePEMKey.pub").read()
>>> from Crypto.PublicKey import RSA
>>> key = RSA.import_key(kt)
>>> key
<_RSAobj #0x109916d40 n(2048),e>
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
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)
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)
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
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)
I have not found a way to load an RSA private key from a PEM file to use it in python-crypto (signature).
python-openssl can load a PEM file but the PKey object can't be used to retrieved key information (p, q, ...) to use with Crypto.PublicKey.construct().
I recommend M2Crypto instead of python-crypto. You will need M2Crypto to parse PEM anyway and its EVP api frees your code from depending on a particular algorithm.
private = """
-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBANQNY7RD9BarYRsmMazM1hd7a+u3QeMPFZQ7Ic+BmmeWHvvVP4Yj
yu1t6vAut7mKkaDeKbT3yiGVUgAEUaWMXqECAwEAAQJAIHCz8h37N4ScZHThYJgt
oIYHKpZsg/oIyRaKw54GKxZq5f7YivcWoZ8j7IQ65lHVH3gmaqKOvqdAVVt5imKZ
KQIhAPPsr9i3FxU+Mac0pvQKhFVJUzAFfKiG3ulVUdHgAaw/AiEA3ozHKzfZWKxH
gs8v8ZQ/FnfI7DwYYhJC0YsXb6NSvR8CIHymwLo73mTxsogjBQqDcVrwLL3GoAyz
V6jf+/8HvXMbAiEAj1b3FVQEboOQD6WoyJ1mQO9n/xf50HjYhqRitOnp6ZsCIQDS
AvkvYKc6LG8IANmVv93g1dyKZvU/OQkAZepqHZB2MQ==
-----END RSA PRIVATE KEY-----
"""
message = "python-crypto sucks"
# Grab RSA parameters e, n
from M2Crypto import RSA, BIO
bio = BIO.MemoryBuffer(private)
rsa = RSA.load_key_bio(bio)
n, e = rsa.n, rsa.e
# In Python-crypto:
import Crypto.PublicKey.RSA
pycrypto_key = Crypto.PublicKey.RSA.construct((n, e))
# Use EVP api to sign message
from M2Crypto import EVP
key = EVP.load_key_string(private)
# if you need a different digest than the default 'sha1':
key.reset_context(md='sha256')
key.sign_init()
key.sign_update(message)
signature = key.sign_final()
# Use EVP api to verify signature
public = """
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANQNY7RD9BarYRsmMazM1hd7a+u3QeMP
FZQ7Ic+BmmeWHvvVP4Yjyu1t6vAut7mKkaDeKbT3yiGVUgAEUaWMXqECAwEAAQ==
-----END PUBLIC KEY-----
"""
from M2Crypto import BIO, RSA, EVP
bio = BIO.MemoryBuffer(public)
rsa = RSA.load_pub_key_bio(bio)
pubkey = EVP.PKey()
pubkey.assign_rsa(rsa)
pubkey.reset_context(md="sha256")
pubkey.verify_init()
pubkey.verify_update(message)
assert pubkey.verify_final(signature) == 1
See http://svn.osafoundation.org/m2crypto/trunk/tests/test_rsa.py, but I prefer using the algorithm-independent EVP API http://svn.osafoundation.org/m2crypto/trunk/tests/test_evp.py.
How do you verify an RSA SHA1 signature in Python? addresses a similar issue.
is this (close to) what you tried doing?
public_key_filename = 'public_key.pem'
rsa = M2Crypto.RSA.load_pub_key(pk)
That should work. The issue might be with openssl too, does it work when you just use openssl (not in Python)?
Link to Me Too Crypto