Edit

Share via


Bring your own key specification

This document describes specifications for importing HSM-protected keys from customers' on-premises HSMs into Key Vault.

Scenario

A Key Vault customer wants to securely transfer a key from their on-premises HSM outside Azure, into the HSM backing Azure Key Vault. This process is called bring your own key (BYOK).

The following requirements apply:

  • The key to transfer never exists outside an HSM in plain text form.
  • Outside an HSM, the key to transfer is always protected by a key held in the Azure Key Vault HSM.

Terminology

Key Name Key Type Origin Description
Key Exchange Key (KEK) RSA Azure Key Vault HSM An HSM backed RSA key pair generated in Azure Key Vault
Wrapping Key oct Vendor HSM An [ephemeral] oct key generated by HSM on-premises
Target Key RSA, EC, oct (Managed HSM only) Vendor HSM The key to transfer to the Azure Key Vault HSM

Key Exchange Key: An HSM-backed key that you generate in the key vault where you import the BYOK key. This KEK must have the following properties:

  • It's an RSA-HSM key (4096-bit, 3072-bit, or 2048-bit).
  • It has a fixed key_ops (ONLY import), that you can use only during BYOK.
  • It must be in the same vault where you import the Target Key.

User steps

To perform a key transfer, a user performs the following steps:

  1. Generate KEK.
  2. Retrieve the public key of the KEK.
  3. Use the HSM vendor-provided BYOK tool to import the KEK into the target HSM and export the target key protected by the KEK.
  4. Import the protected target key to Azure Key Vault.

Customers use the BYOK tool and documentation provided by the HSM vendor to complete step 3. It produces a key transfer blob (a .byok file).

HSM constraints

Existing HSMs might apply constraints on keys that they manage, including:

  • You might need to configure the HSM to allow key wrap-based export.
  • You might need to mark the target key as CKA_EXTRACTABLE for the HSM to allow controlled export.
  • In some cases, you might need to mark the KEK and wrapping key as CKA_TRUSTED, which allows it to be used to wrap keys in the HSM.

The configuration of the source HSM is generally outside the scope of this specification. Microsoft expects the HSM vendor to produce documentation accompanying their BYOK tool to include any such configuration steps.

Note

You can perform several of these steps by using other interfaces such as Azure PowerShell and Azure portal. You can also perform these steps programmatically by using equivalent functions in Key Vault SDK.

Generate KEK

Use the az keyvault key create command to create a KEK with key operations set to import. Note the key identifier kid returned from this command.

az keyvault key create --kty RSA-HSM --size 4096 --name KEKforBYOK --ops import --vault-name ContosoKeyVaultHSM

Note

Services support different KEK lengths. Azure SQL, for instance, only supports key lengths of 2048 or 3072 bytes. Consult the documentation for your service for specifics.

Retrieve the public key of the KEK

Download the public key portion of the KEK and store it in a PEM file.

az keyvault key download --name KEKforBYOK --vault-name ContosoKeyVaultHSM --file KEKforBYOK.publickey.pem

Generate key transfer blob by using HSM vendor provided BYOK tool

Use the HSM vendor provided BYOK tool to create a key transfer blob (stored as a .byok file). The tool takes the KEK public key as a .pem file as one of its inputs.

Key transfer blob

Microsoft plans to use the PKCS#11 CKM_RSA_AES_KEY_WRAP mechanism to transfer the target key to Azure Key Vault. This mechanism produces a single blob, and more importantly, the two HSMs handle the intermediate AES key and guarantee it is ephemeral. This mechanism isn't currently available in some HSMs, but the combination of protecting the target key by using CKM_AES_KEY_WRAP_PAD with an AES key and protecting the AES key by using CKM_RSA_PKCS_OAEP creates an equivalent blob.

The target key plaintext depends on the key type:

  • For an RSA key, the private key uses ASN.1 DER encoding [RFC3447] wrapped in PKCS#8 [RFC5208].
  • For an EC key, the private key uses ASN.1 DER encoding [RFC5915] wrapped in PKCS#8 [RFC5208].
  • For an octet key, the key uses raw bytes.

The process transforms the bytes for the plaintext key by using the CKM_RSA_AES_KEY_WRAP mechanism:

  • The process generates an ephemeral oct key and encrypts it by using the wrapping RSA key and RSA-OAEP with SHA1.
  • The process encrypts the encoded plaintext key by using the oct key and AES Key Wrap with Padding.
  • The process concatenates the encrypted oct key and the encrypted plaintext key to produce the final ciphertext blob.

The transfer blob format uses JSON Web Encryption compact serialization (RFC7516) primarily as a vehicle for delivering the required metadata to the service for correct decryption.

If you use CKM_RSA_AES_KEY_WRAP_PAD, the JSON serialization of the transfer blob is:

{
  "schema_version": "1.0.0",
  "header":
  {
    "kid": "<key identifier of the KEK>",
    "alg": "dir",
    "enc": "CKM_RSA_AES_KEY_WRAP"
  },
  "ciphertext":"BASE64URL(<ciphertext contents>)",
  "generator": "BYOK tool name and version; source HSM name and firmware version"
}

  • kid = key identifier of KEK. For Key Vault keys, it looks like this: https://ContosoKeyVaultHSM.vault.azure.net/keys/mykek/eba63d27e4e34e028839b53fac905621
  • alg = algorithm.
  • dir = Direct mode. The referenced kid directly protects the ciphertext, which is an accurate representation of CKM_RSA_AES_KEY_WRAP.
  • generator = an informational field that denotes the name and version of BYOK tool and the source HSM manufacturer and model. Use this information for troubleshooting and support.

Store the JSON blob in a file with a .byok extension so that the Azure PowerShell or CLI client treats it correctly when you use the Add-AzKeyVaultKey (PowerShell) or az keyvault key import (CLI) commands.

Upload key transfer blob to import HSM-key

To import a key, transfer the Key Transfer Blob (".byok" file) to an online workstation, and then run the az keyvault key import command. This command imports the blob as a new HSM-backed key into Key Vault.

To import an RSA key, use the following command:

az keyvault key import --vault-name ContosoKeyVaultHSM --name ContosoFirstHSMkey --byok-file KeyTransferPackage-ContosoFirstHSMkey.byok --ops encrypt decrypt

To import an EC key, specify the key type and the curve name.

az keyvault key import --vault-name ContosoKeyVaultHSM --name ContosoFirstHSMkey --kty EC-HSM --curve-name "P-256" --byok-file KeyTransferPackage-ContosoFirstHSMkey.byok --ops sign verify

When you run this command, it sends a REST API request as follows:

PUT https://contosokeyvaulthsm.vault.azure.net/keys/ContosoFirstHSMKey?api-version=7.0

Request body when importing an RSA key:

{
  "key": {
    "kty": "RSA-HSM",
    "key_ops": [
      "decrypt",
      "encrypt"
    ],
    "key_hsm": "<Base64 encoded BYOK_BLOB>"
  },
  "attributes": {
    "enabled": true
  }
}

Request body when importing an EC key:

{
  "key": {
    "kty": "EC-HSM",
    "crv": "P-256",
    "key_ops": [
      "sign",
      "verify"
    ],
    "key_hsm": "<Base64 encoded BYOK_BLOB>"
  },
  "attributes": {
    "enabled": true
  }
}

The key_hsm value is the entire contents of the KeyTransferPackage-ContosoFirstHSMkey.byok file, encoded in Base64 format.

References

Next steps