Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Cryptography export key to DER

In the past when using PyCrypto I was able to do the following to generate a fingerprint of a RSA public key:

rsa_cipher = PKCS1_v1_5.new(RSA.importKey(pub_rsa_key))
hashlib.sha1(rsa_cipher._key.exportKey("DER")).hexdigest()

How can I achieve the same without PyCrypto?


EDIT

What I provide in pub_rsa_key is a content of a .perm file, i.e.:

-----BEGIN PUBLIC KEY-----
MII...AB
-----END PUBLIC KEY-----

PyCrypto is deemed unsafe and is not maintained anymore so I switched to Python's Cryptography but it seems that it does not have an adequate feature.

  • Is there similar functionality that I missed in the Pythons Cryptography API?
  • Is PyCryptoDome possible is a worthy (stable and safe) replacement for PyCrypto to use to implement this functionality?
  • If none of the above is it possible to export that key in a DER format by a self written function?

Any documentation or search terms to perform the export would be helpful.


EDIT 2
Maarten Bodewes' comments (thank you) took me to a place that seems to be the thing I was looking for. But the results of the DER export differ:

# Python 3.7 using Cryptography
from cryptography.hazmat.primitives import serialization

with open('pub_key.perm', 'rb') as key_file: 
    public_key = serialization.load_pem_public_key(key_file.read(), backend=default_backend())

pub_der = public_key.public_bytes(encoding=serialization.Encoding.DER, format=serialization.PublicFormat.PKCS1)

print(sha1(pub_der).hexdigest())
# gives "d291c142648b7........c2f4676f4213203c4bd"

where

# Python 2.7 using PyCrypto
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA

with open('pub_key.perm', 'r') as key_file:
    public_key = RSA.importKey(key_file.read())

pub_der = public_key.exportKey('DER')  # this assumes PKCS1 by default per the __doc__

print(sha1(pub_der).hexdigest())
# gives "bb070664079f5........64c97fcadbad847cce9"

This is an effort to move from Py2 to Py3 - please notice that the two examples use different Python versions. Could encoding be an issue here?

like image 350
McAbra Avatar asked Oct 16 '22 07:10

McAbra


1 Answers

To answer my question (which was resolved with the help provided in the comments, thanks again).

To achieve what I was able to do with PyCrypto:

# Python 2.7 using PyCrypto
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA

with open('pub_key.perm', 'r') as key_file:
    public_key = RSA.importKey(key_file.read())

pub_der = public_key.exportKey('DER')  # this assumes PKCS1 by default per the __doc__

print(sha1(pub_der).hexdigest())
# gives "bb070664079f5........64c97fcadbad847cce9"

with Cryptography, one can do the following:

# Python 3.7 using Cryptography
from cryptography.hazmat.primitives import serialization

with open('pub_key.perm', 'rb') as key_file: 
    public_key = serialization.load_pem_public_key(key_file.read(), backend=default_backend())

pub_der = public_key.public_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PublicFormat.SubjectPublicKeyInfo,
)

print(sha1(pub_der).hexdigest())
# gives "bb070664079f5........64c97fcadbad847cce9"
like image 103
McAbra Avatar answered Oct 20 '22 01:10

McAbra