Search code examples
pythoncryptographypublic-keypython-cryptography

Loading Public Key (DER Format) from Hex in Python


I have a public key raw data (Which is extracted from NFC Chip of a machine readable travelling document.) However I want to execute the active authentication on cloud as well as the internal IC chip.

The snippet below shows the loading implementation with python's cryptography library.

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_der_public_key
_pub_key="6F81E03081DD300...."
pub_key_bytes = bytes.fromhex(_pub_key)
print(pub_key_bytes)
load_der_public_key(data = pub_key_bytes,backend=default_backend())

Which throws the error;

ValueError: Could not deserialize key data.

Which corresponds to this (in their documentation.)

Raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError

Also; I know the public key is in the correct format (at least on the beginning) since first byte is 0/, which is the required magic byte for DER formats.

I'm also aware of public key being 454 characters long, whereas RSA public keys have 256 bytes in length, (Which is equal to 512 hex characters.)

I tried adding right padding in order to complete the key to 512 characters as:

_pub_key = _pub_key+f"{'0'*(512-len(_pub_key))}"

Which also resulted in the same error.

PS: I know the key is valid because in successfully completes the authentication (sign + verify) in the microprocessor.

Link to My Public Key


Solution

  • You have to remove the first three bytes of the data i.e. 0x6F81E0. The rest, i.e. 0x3081DD...010001 is the actual key (DER encoded, X.509/SPKI format, 1536 bits). You can check this with an ASN.1 parser, e.g. https://lapo.it/asn1js/.


    For completeness: The size of an RSA key corresponds to the size of the modulus. For security reasons, RSA keys today should be at least 2048 bits in size. In addition to the modulus, an RSA key has other parameters, e.g. for a public key the public exponent.
    RSA keys can be encapsulated in different formats, e.g. the posted key is an ASN.1/DER encoded public key in X.509/SPKI format. Such a key is larger than the size of the modulus because of the additional parameters and the format-dependent metadata.
    ASN.1/DER encoded keys generally do not start with 0x00. However, the ASN.1/DER encoding rules can result in 0x00 values occurring within the data (of course, the key parameters themselves can also contain 0x00 values).