skip to Main Content

Is there a python sdk call to download the publickey in .pem format from the azure keyvault.

Yes, we can download the publickey using the Az CLI "az keyvault key download " and directly using the azure portal, but we are looking for the python sdk call

Below code only gives the key name or version of key but not the actual public key
get_key retrieves a key previously stored in the Vault.

from azure.identity import DefaultAzureCredential
from azure.keyvault.keys import KeyClient

credential = DefaultAzureCredential()

key_client = KeyClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential)
key = key_client.get_key("key-name")
print(key.name)

key = key_client.get_key("key-name") >> gives the key name stored in the keyvault not the actual public key

we are looking for

—–BEGIN PUBLIC KEY—–
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzkA+yiEvKHY5SbCcwwY376BZHowPTeDpLzKuAAd5N0QMjCu8GS8OVDnkhu1NxZl30OqvTTVTdd756TOAtALy3/dVVJbe/rB7K0ry/+mkZoWz922KgqXb+BeF+TMficf+zOgkd1PIkzuiiI4OMbIDnLqEd5Hka1RQFwKCzrHHA+V29LJWH0geHe1Q/REaAI/eq5yiIIXcudwpN3ngAKvgDYnX+J0R7fwie1DzzZfdC4sBZfeOthI4aFIfSCAKejnDeLAS3PcQUfh61b6xj+5rZts0zISx7Dz3RQFQIDAQAB
—–END PUBLIC KEY—–

Please anyone who is aware of this issue, can bring some light into it.

4

Answers


  1. Chosen as BEST ANSWER

    we can download the public key in .pem format from the azure key-vault.

    Register the service principal with the key vault

            self.KVUri = f"https://{keyVaultName}.vault.azure.net"
        self.credential = ClientSecretCredential(
            tenant_id="xxxxxxxxxxxxxxxxxxxxxxxxx",
            client_id="xxxxxxxxxxxxxxxxxxxxxxxxx",
            client_secret="xxxxxxxxxxxxxxxxxxxxxxxxx")
        self.key_client = KeyClient(vault_url=self.KVUri,
                                    credential=self.credential)
    

    First, generate the key in the keyvault

    key_client.create_rsa_key("key-name", 2048)
    

    Code snippet to download the public key:

        key = self.key_client.get_key(device_name)
        # use a key's JsonWebKey or JWK class (A fetched key's .key property)
        # to construct a PEM of the public key.
        usable_jwk = {}
        for k in vars(key.key):
            value = vars(key.key)[k]
            if value:
                usable_jwk[k] = urlsafe_b64encode(value) if isinstance(
                    value, bytes) else value
    
        # The following code is meant for RSA keys
        # For EC keys, use `jwt.algorithms.ECAlgorithm.from_jwk(usable_jwk)`
    
        public_key = jwt.algorithms.RSAAlgorithm.from_jwk(usable_jwk)
        public_pem = public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        )
    

    public_pem is the publicKey in .pem format.


  2. You only get the public key when you download the get_key from Azure Key Vault, to get the private key, you need to download it as a secret instead.

    Yes, it is strange….

    Login or Signup to reply.
  3. The only way to get public key of the certificate (assumption based on PEM format) in that format is to download secret portion which will include both public and private in that format.

    In the code above you print key name of the key, so it shows just name:
    print(key.name)

    Try print(key.n), for more information about available properties of return JSONWEBKey see: https://learn.microsoft.com/en-us/python/api/azure-keyvault-keys/azure.keyvault.keys.jsonwebkey?view=azure-python

    Login or Signup to reply.
  4. As Jack mentioned in another answer, the public (and private) key of a certificate can be fetched from the secret associated with a certificate — here is a sample that demonstrates this.

    You seem to want the public key of a Key Vault key though, rather than the key of a certificate. There’s no straightforward way to fetch this with azure-keyvault-keys, but you can use a key’s JWK (a fetched key’s .key property) to construct a PEM of the public key.

    The following sample shows how to do this with an RSA key, but explains how you can adjust it for EC keys as well:

    from base64 import urlsafe_b64encode
    from cryptography.hazmat.primitives import serialization
    import jwt
    
    from azure.identity import DefaultAzureCredential
    from azure.keyvault.keys import KeyClient
    
    
    vault_url= "https://{vault-name}.vault.azure.net"
    credential = DefaultAzureCredential()
    client = KeyClient(vault_url, credential)
    
    key = client.get_key("{key-name}")
    
    # The JsonWebKey in `key.key` is correct, but may contain fields with None values
    usable_jwk = {}
    for k in vars(key.key):
        value = vars(key.key)[k]
        if value:
            usable_jwk[k] = urlsafe_b64encode(value) if isinstance(value, bytes) else value
    
    # The following code is meant for RSA keys
    # For EC keys, use `jwt.algorithms.ECAlgorithm.from_jwk(usable_jwk)`
    public_key = jwt.algorithms.RSAAlgorithm.from_jwk(usable_jwk)
    public_pem = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    )
    print(public_pem)
    

    (I work with the Azure SDK in Python)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search