Microsoft Azure Key Vault Client Libraries for Python providing unified access to keys, secrets, and certificates
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
High-performance cryptographic operations using keys stored in Azure Key Vault. Provides encryption, decryption, digital signing, verification, and key wrapping capabilities with support for various algorithms. Enables both local and remote cryptographic operations depending on key type and requirements.
Client for performing cryptographic operations with Azure Key Vault keys.
class CryptographyClient:
def __init__(self, key, credential, **kwargs):
"""
Initialize CryptographyClient for cryptographic operations.
Parameters:
- key: KeyVaultKey or JsonWebKey, key to use for operations
- credential: Azure credential object for authentication
- **kwargs: Additional configuration options
"""
@classmethod
def from_jwk(cls, jwk: JsonWebKey) -> "CryptographyClient":
"""
Create client from JSON Web Key for local operations.
Parameters:
- jwk: JsonWebKey, key material for local operations
Returns:
CryptographyClient configured for local operations
"""
def close(self) -> None:
"""Close the client and release resources."""Encrypt and decrypt data using various symmetric and asymmetric algorithms.
def encrypt(self, algorithm: EncryptionAlgorithm, plaintext: bytes, **kwargs) -> EncryptResult:
"""
Encrypt data using the specified algorithm.
Parameters:
- algorithm: EncryptionAlgorithm, encryption algorithm to use
- plaintext: bytes, data to encrypt
- iv: bytes, initialization vector for symmetric algorithms
- additional_authenticated_data: bytes, AAD for authenticated encryption
Returns:
EncryptResult with encrypted data and metadata
"""
def decrypt(self, algorithm: EncryptionAlgorithm, ciphertext: bytes, **kwargs) -> DecryptResult:
"""
Decrypt data using the specified algorithm.
Parameters:
- algorithm: EncryptionAlgorithm, decryption algorithm to use
- ciphertext: bytes, encrypted data to decrypt
- iv: bytes, initialization vector for symmetric algorithms
- additional_authenticated_data: bytes, AAD for authenticated encryption
- authentication_tag: bytes, authentication tag for authenticated encryption
Returns:
DecryptResult with decrypted data and metadata
"""Sign data and verify signatures using various algorithms.
def sign(self, algorithm: SignatureAlgorithm, digest: bytes, **kwargs) -> SignResult:
"""
Sign a digest using the specified algorithm.
Parameters:
- algorithm: SignatureAlgorithm, signature algorithm to use
- digest: bytes, pre-computed hash to sign
Returns:
SignResult with signature and metadata
"""
def verify(self, algorithm: SignatureAlgorithm, digest: bytes, signature: bytes, **kwargs) -> VerifyResult:
"""
Verify a signature using the specified algorithm.
Parameters:
- algorithm: SignatureAlgorithm, signature algorithm used
- digest: bytes, original hash that was signed
- signature: bytes, signature to verify
Returns:
VerifyResult with verification status and metadata
"""Wrap and unwrap keys for secure key exchange and storage.
def wrap_key(self, algorithm: KeyWrapAlgorithm, key: bytes, **kwargs) -> WrapResult:
"""
Wrap (encrypt) a key using the specified algorithm.
Parameters:
- algorithm: KeyWrapAlgorithm, key wrapping algorithm to use
- key: bytes, key material to wrap
Returns:
WrapResult with wrapped key and metadata
"""
def unwrap_key(self, algorithm: KeyWrapAlgorithm, encrypted_key: bytes, **kwargs) -> UnwrapResult:
"""
Unwrap (decrypt) a key using the specified algorithm.
Parameters:
- algorithm: KeyWrapAlgorithm, key unwrapping algorithm to use
- encrypted_key: bytes, wrapped key to unwrap
Returns:
UnwrapResult with unwrapped key and metadata
"""class EncryptionAlgorithm(str, Enum):
"""Supported encryption algorithms."""
# RSA algorithms
rsa1_5 = "RSA1_5" # RSA with PKCS#1 v1.5 padding
rsa_oaep = "RSA-OAEP" # RSA with OAEP padding (SHA-1)
rsa_oaep_256 = "RSA-OAEP-256" # RSA with OAEP padding (SHA-256)
# AES GCM algorithms
a128gcm = "A128GCM" # AES-128 GCM
a192gcm = "A192GCM" # AES-192 GCM
a256gcm = "A256GCM" # AES-256 GCM
# AES Key Wrap algorithms
a128kw = "A128KW" # AES-128 Key Wrap
a192kw = "A192KW" # AES-192 Key Wrap
a256kw = "A256KW" # AES-256 Key Wrap
# AES CBC algorithms
a128cbc = "A128CBC" # AES-128 CBC
a192cbc = "A192CBC" # AES-192 CBC
a256cbc = "A256CBC" # AES-256 CBC
# AES CBC with PKCS#7 padding
a128cbcpad = "A128CBCPAD" # AES-128 CBC with PKCS#7 padding
a192cbcpad = "A192CBCPAD" # AES-192 CBC with PKCS#7 padding
a256cbcpad = "A256CBCPAD" # AES-256 CBC with PKCS#7 paddingclass KeyWrapAlgorithm(str, Enum):
"""Supported key wrapping algorithms."""
# RSA algorithms
rsa1_5 = "RSA1_5" # RSA with PKCS#1 v1.5 padding
rsa_oaep = "RSA-OAEP" # RSA with OAEP padding (SHA-1)
rsa_oaep_256 = "RSA-OAEP-256" # RSA with OAEP padding (SHA-256)
# AES Key Wrap algorithms
a128kw = "A128KW" # AES-128 Key Wrap
a192kw = "A192KW" # AES-192 Key Wrap
a256kw = "A256KW" # AES-256 Key Wrapclass SignatureAlgorithm(str, Enum):
"""Supported signature algorithms."""
# RSA PSS algorithms
ps256 = "PS256" # RSA-PSS with SHA-256
ps384 = "PS384" # RSA-PSS with SHA-384
ps512 = "PS512" # RSA-PSS with SHA-512
# RSA PKCS#1 v1.5 algorithms
rs256 = "RS256" # RSA with SHA-256
rs384 = "RS384" # RSA with SHA-384
rs512 = "RS512" # RSA with SHA-512
# ECDSA algorithms
es256 = "ES256" # ECDSA with SHA-256 (P-256 curve)
es384 = "ES384" # ECDSA with SHA-384 (P-384 curve)
es512 = "ES512" # ECDSA with SHA-512 (P-521 curve)
es256k = "ES256K" # ECDSA with SHA-256 (secp256k1 curve)class EncryptResult:
"""Result of encryption operation."""
key_id: str
algorithm: EncryptionAlgorithm
ciphertext: bytes
iv: bytes # Initialization vector (if applicable)
authentication_tag: bytes # Authentication tag (for authenticated encryption)
class DecryptResult:
"""Result of decryption operation."""
key_id: str
algorithm: EncryptionAlgorithm
plaintext: bytes
class WrapResult:
"""Result of key wrap operation."""
key_id: str
algorithm: KeyWrapAlgorithm
encrypted_key: bytes
class UnwrapResult:
"""Result of key unwrap operation."""
key_id: str
algorithm: KeyWrapAlgorithm
key: bytes
class SignResult:
"""Result of sign operation."""
key_id: str
algorithm: SignatureAlgorithm
signature: bytes
class VerifyResult:
"""Result of verify operation."""
key_id: str
algorithm: SignatureAlgorithm
is_valid: boolfrom azure.keyvault.keys import KeyClient
from azure.keyvault.keys.crypto import EncryptionAlgorithm
from azure.identity import DefaultAzureCredential
# Initialize clients
credential = DefaultAzureCredential()
key_client = KeyClient(vault_url="https://vault-name.vault.azure.net/", credential=credential)
# Create RSA key for encryption
rsa_key = key_client.create_rsa_key("encryption-key", size=2048)
# Get cryptography client
crypto_client = key_client.get_cryptography_client("encryption-key")
# Encrypt data
plaintext = b"This is sensitive data that needs to be encrypted"
encrypt_result = crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep, plaintext)
print(f"Encrypted with key: {encrypt_result.key_id}")
print(f"Ciphertext length: {len(encrypt_result.ciphertext)} bytes")
# Decrypt data
decrypt_result = crypto_client.decrypt(EncryptionAlgorithm.rsa_oaep, encrypt_result.ciphertext)
print(f"Decrypted: {decrypt_result.plaintext.decode()}")from azure.keyvault.keys.crypto import EncryptionAlgorithm
import os
# Create AES key
aes_key = key_client.create_oct_key("aes-key", size=256)
aes_crypto_client = key_client.get_cryptography_client("aes-key")
# AES-GCM encryption (authenticated encryption)
plaintext = b"Symmetric encryption with AES-256-GCM"
iv = os.urandom(12) # 96-bit IV for GCM
aad = b"additional authenticated data"
encrypt_result = aes_crypto_client.encrypt(
EncryptionAlgorithm.a256gcm,
plaintext,
iv=iv,
additional_authenticated_data=aad
)
# Decrypt with authentication
decrypt_result = aes_crypto_client.decrypt(
EncryptionAlgorithm.a256gcm,
encrypt_result.ciphertext,
iv=iv,
additional_authenticated_data=aad,
authentication_tag=encrypt_result.authentication_tag
)
print(f"Decrypted: {decrypt_result.plaintext.decode()}")from azure.keyvault.keys.crypto import SignatureAlgorithm
import hashlib
# Create EC key for signing
ec_key = key_client.create_ec_key("signing-key", curve="P-256")
sign_crypto_client = key_client.get_cryptography_client("signing-key")
# Create hash of data to sign
data = b"This document needs to be digitally signed"
digest = hashlib.sha256(data).digest()
# Sign the hash
sign_result = sign_crypto_client.sign(SignatureAlgorithm.es256, digest)
print(f"Signature length: {len(sign_result.signature)} bytes")
# Verify signature
verify_result = sign_crypto_client.verify(SignatureAlgorithm.es256, digest, sign_result.signature)
print(f"Signature valid: {verify_result.is_valid}")
# Verify with tampered data (should fail)
tampered_data = b"This document has been tampered with"
tampered_digest = hashlib.sha256(tampered_data).digest()
verify_tampered = sign_crypto_client.verify(SignatureAlgorithm.es256, tampered_digest, sign_result.signature)
print(f"Tampered signature valid: {verify_tampered.is_valid}")from azure.keyvault.keys.crypto import KeyWrapAlgorithm
import os
# Create RSA key for key wrapping
wrap_key = key_client.create_rsa_key("key-wrap-key", size=2048)
wrap_crypto_client = key_client.get_cryptography_client("key-wrap-key")
# Generate symmetric key to wrap
symmetric_key = os.urandom(32) # 256-bit key
# Wrap the symmetric key
wrap_result = wrap_crypto_client.wrap_key(KeyWrapAlgorithm.rsa_oaep, symmetric_key)
print(f"Wrapped key length: {len(wrap_result.encrypted_key)} bytes")
# Unwrap the key
unwrap_result = wrap_crypto_client.unwrap_key(KeyWrapAlgorithm.rsa_oaep, wrap_result.encrypted_key)
print(f"Keys match: {unwrap_result.key == symmetric_key}")
# Use AES key wrapping
aes_wrap_key = key_client.create_oct_key("aes-wrap-key", size=256)
aes_wrap_crypto_client = key_client.get_cryptography_client("aes-wrap-key")
# Wrap with AES-KW
aes_wrap_result = aes_wrap_crypto_client.wrap_key(KeyWrapAlgorithm.a256kw, symmetric_key)
aes_unwrap_result = aes_wrap_crypto_client.unwrap_key(KeyWrapAlgorithm.a256kw, aes_wrap_result.encrypted_key)
print(f"AES wrapped keys match: {aes_unwrap_result.key == symmetric_key}")from azure.keyvault.keys.crypto import CryptographyClient
# Get key with private key material (for HSM keys, operations are always remote)
key_with_private = key_client.get_key("encryption-key")
# Create local crypto client
local_crypto_client = CryptographyClient.from_jwk(key_with_private.key)
# Local operations (faster, no network calls)
local_encrypt_result = local_crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep, plaintext)
local_decrypt_result = local_crypto_client.decrypt(EncryptionAlgorithm.rsa_oaep, local_encrypt_result.ciphertext)
print(f"Local operation successful: {local_decrypt_result.plaintext == plaintext}")from azure.keyvault.keys.crypto import EncryptionAlgorithm
import os
# Multi-layer encryption example
outer_key = key_client.create_rsa_key("outer-key", size=2048)
inner_key = key_client.create_oct_key("inner-key", size=256)
outer_crypto = key_client.get_cryptography_client("outer-key")
inner_crypto = key_client.get_cryptography_client("inner-key")
sensitive_data = b"Top secret information requiring multi-layer encryption"
# Layer 1: AES-GCM encryption
iv = os.urandom(12)
inner_result = inner_crypto.encrypt(EncryptionAlgorithm.a256gcm, sensitive_data, iv=iv)
# Layer 2: RSA encryption of the AES-encrypted data
outer_result = outer_crypto.encrypt(EncryptionAlgorithm.rsa_oaep, inner_result.ciphertext)
print("Multi-layer encryption complete")
# Decrypt layers in reverse order
outer_decrypt = outer_crypto.decrypt(EncryptionAlgorithm.rsa_oaep, outer_result.ciphertext)
inner_decrypt = inner_crypto.decrypt(
EncryptionAlgorithm.a256gcm,
outer_decrypt.plaintext,
iv=iv,
authentication_tag=inner_result.authentication_tag
)
print(f"Multi-layer decryption successful: {inner_decrypt.plaintext == sensitive_data}")from azure.keyvault.keys.aio import KeyClient
from azure.keyvault.keys.crypto.aio import CryptographyClient
import asyncio
async def async_crypto_operations():
credential = DefaultAzureCredential()
key_client = KeyClient(vault_url="https://vault-name.vault.azure.net/", credential=credential)
try:
# Create key asynchronously
key = await key_client.create_rsa_key("async-key", size=2048)
# Get async crypto client
crypto_client = await key_client.get_cryptography_client("async-key")
try:
# Async encryption
plaintext = b"Async encryption test"
encrypt_result = await crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep, plaintext)
# Async decryption
decrypt_result = await crypto_client.decrypt(EncryptionAlgorithm.rsa_oaep, encrypt_result.ciphertext)
print(f"Async operation successful: {decrypt_result.plaintext == plaintext}")
finally:
await crypto_client.close()
finally:
await key_client.close()
# Run async operations
asyncio.run(async_crypto_operations())Install with Tessl CLI
npx tessl i tessl/pypi-azure-keyvault