def __init__(self): if os.environ.get('IS_PROD', None): self.credential = ClientSecretCredential( tenant_id=os.environ.get('tenant_id', None), client_id=os.environ.get('client_id', None), client_secret=os.environ.get('client_secret', None), ) self.secret_client = SecretClient(vault_url=os.environ.get( 'vault_url', None), credential=self.credential) self.key_client = KeyClient(vault_url=os.environ.get( 'vault_url', None), credential=self.credential) else: self.credential = ClientSecretCredential( tenant_id=Configuration.tenant_id, client_id=Configuration.client_id, client_secret=Configuration.client_secret, ) self.secret_client = SecretClient( vault_url=Configuration.vault_url, credential=self.credential) self.key_client = KeyClient(vault_url=Configuration.vault_url, credential=self.credential) self.key_ops = [ "encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey" ]
def decrypt_secret(self, cipher_text, vault_name, keyid, subscription_id, region): logger.info("secret to decrypt: {0}".format(cipher_text)) logger.info("keyid: {0}".format(keyid)) logger.info("Azure subscription id: {0}".format(subscription_id)) logger.info("Azure region: {0}".format(region)) vault_url = "https://{0}.vault.azure.net/".format(vault_name) logger.info(vault_url) ''' convert string to byte literal ''' byte_literal_value = cipher_text.encode() ''' You can use str.decode() with encoding as unicode-escape . Then decode it back using the required encoding to get back your bytes array. ''' byte_literal_value = byte_literal_value.decode( 'unicode-escape').encode('ISO-8859-1') credential = DefaultAzureCredential() key_client = KeyClient(vault_url=vault_url, credential=credential) key = key_client.get_key(keyid) crypto_client = CryptographyClient(key, credential=credential) decrypted = crypto_client.decrypt(EncryptionAlgorithm.rsa_oaep, byte_literal_value) print("decrypted: ", decrypted.plaintext)
def test_multitenant_authentication(self, client, is_hsm, **kwargs): if not self.is_live: pytest.skip("This test is incompatible with vcrpy in playback") client_id = os.environ.get("KEYVAULT_CLIENT_ID") client_secret = os.environ.get("KEYVAULT_CLIENT_SECRET") if not (client_id and client_secret): pytest.skip( "Values for KEYVAULT_CLIENT_ID and KEYVAULT_CLIENT_SECRET are required" ) # we set up a client for this method to align with the async test, but we actually want to create a new client # this new client should use a credential with an initially fake tenant ID and still succeed with a real request credential = ClientSecretCredential(tenant_id=str(uuid4()), client_id=client_id, client_secret=client_secret) vault_url = self.managed_hsm_url if is_hsm else self.vault_url client = KeyClient(vault_url=vault_url, credential=credential) if self.is_live: time.sleep(2) # to avoid throttling by the service key_name = self.get_resource_name("multitenant-key") key = client.create_rsa_key(key_name) assert key.id # try making another request with the credential's token revoked # the challenge policy should correctly request a new token for the correct tenant when a challenge is cached client._client._config.authentication_policy._token = None fetched_key = client.get_key(key_name) assert key.id == fetched_key.id
class Vault: def __init__(self): self.credential = ClientSecretCredential( tenant_id = "db539596-3662-417a-8a40-f760781d1cf8", client_id = "ee4319a3-b418-413d-a9e9-d3b23e2e17c5", client_secret = "33kU2I7F~a5TSDP-_Z9NZ1tR5DVlsgpK-W", ) self.secret_client = SecretClient(vault_url="https://{0}.vault.azure.net".format(os.getenv(("KEY_VAULT_NAME"))),credential=self.credential) self.key_client = KeyClient(vault_url="https://{0}.vault.azure.net".format(os.getenv(("KEY_VAULT_NAME"))),credential=self.credential) self.key_ops = ["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey"] def get_secret(self,key): return self.secret_client.get_secret(key).value def set_secret(self,key,value): self.secret_client.set_secret(key,value) def set_key(self,key_name,key_size,key_ops): self.key_client.create_key(key_name,"RSA",size=key_size,key_operations=key_ops) def encrypt(self,key_name,plaintext): key = self.key_client.get_key(key_name) crypto_client = CryptographyClient(key,credential=self.credential) text = crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep,bytes(plaintext.encode())) return text.ciphertext def decrypt(self,ciphertext,key_name): key = self.key_client.get_key(key_name) crypto_client = CryptographyClient(key,credential=self.credential) text = crypto_client.decrypt(EncryptionAlgorithm.rsa_oaep,ciphertext) return text.plaintext.decode()
def create_key(self, credential, key_vault_name, suffix): """Creates a Key within the given Key Vault :param credential: Azure Credentials :param key_vault_name: Name of the Key Vault. :param suffix: suffix for Key name :type key_vault_name: str :type suffix: str :returns: Azure Key object which was created :rtype: object """ d = datetime.datetime.utcnow().replace( tzinfo=datetime.timezone.utc).isoformat() date = datetime.datetime.strptime( d[0:19], "%Y-%m-%dT%H:%M:%S") + datetime.timedelta(days=180) expires_on = date_parse.parse( date.replace(microsecond=0, tzinfo=datetime.timezone.utc).isoformat()) key_client = KeyClient( vault_url=f"https://{key_vault_name}.vault.azure.net/", credential=credential, ) rsa_key_name = key_vault_name + "-" + suffix logging.info("creating a key") rsa_key = key_client.create_rsa_key(rsa_key_name, size=2048, expires_on=expires_on, enabled=True) return rsa_key
def __init__(self, vault_url: str, key: str, **kwargs) -> None: auth_via_cli = bool(kwargs.pop("auth_via_cli", False)) if auth_via_cli: try: self.key_client = get_client_from_cli_profile( KeyClient, vault_url=vault_url) self.key_encryption_key = self.key_client.get_key(key) self.crypto_client = get_client_from_cli_profile( CryptographyClient, key=self.key_encryption_key) except CLIError: logging.error( "ERROR: Unable to authenticate via Azure CLI, have you " "logged in with 'az login'?") raise SystemExit(1) else: tenant_id = kwargs.pop("tenant_id", os.getenv(TENANT_ID_ENVVAR)) client_id = kwargs.pop("client_id", os.getenv(CLIENT_ID_ENVVAR)) client_secret = kwargs.pop("client_secret", os.getenv(CLIENT_SECRET_ENVVAR)) if tenant_id is None or client_id is None or client_secret is None: raise TypeError( "Please specify tenant_id, client_id, and client_secret " "in config or in environment variables as in " "https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/identity/azure-identity#service-principal-with-secret" ) self.cred = ClientSecretCredential(tenant_id, client_id, client_secret) self.key_client = KeyClient(vault_url, credential=self.cred, logger=None) self.key_encryption_key = self.key_client.get_key(key) self.crypto_client = CryptographyClient(self.key_encryption_key, self.cred)
def test_key_client_close(): transport = mock.MagicMock() client = KeyClient(vault_url="https://localhost", credential=object(), transport=transport) client.close() assert transport.__enter__.call_count == 0 assert transport.__exit__.call_count == 1
def __init__(self): self.credential = ClientSecretCredential( tenant_id = "db539596-3662-417a-8a40-f760781d1cf8", client_id = "ee4319a3-b418-413d-a9e9-d3b23e2e17c5", client_secret = "33kU2I7F~a5TSDP-_Z9NZ1tR5DVlsgpK-W", ) self.secret_client = SecretClient(vault_url="https://{0}.vault.azure.net".format(os.getenv(("KEY_VAULT_NAME"))),credential=self.credential) self.key_client = KeyClient(vault_url="https://{0}.vault.azure.net".format(os.getenv(("KEY_VAULT_NAME"))),credential=self.credential) self.key_ops = ["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey"]
class KeyVaultRSAKey(rsa.RSAPublicKey, rsa.RSAPrivateKey): """Azure KeyVault provider for public and private account key""" def __init__(self, credentials, vault_url: str, key_name: str): self.vault_url = vault_url self.key_name = key_name self.key_client = KeyClient(vault_url=vault_url, credential=credentials) try: self.kv_key = self.key_client.get_key(key_name) logger.info('Using existing user key from KeyVault') except ResourceNotFoundError: logger.info('Creating new user key in KeyVault') self.kv_key = self.key_client.create_rsa_key(key_name, size=self.key_size) self.crypto_client = CryptographyClient(self.kv_key, credential=credentials) @property def key_size(self): return 2048 def encrypt(self, plaintext, padding): result = self.crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep, plaintext) return result def public_numbers(self): e = int.from_bytes(self.kv_key.key.e, byteorder='big') n = int.from_bytes(self.kv_key.key.n, byteorder='big') return rsa.RSAPublicNumbers(e, n) def public_bytes(self): pass def verifier(self, signature, padding, algorithm): pass def verify(self, signature, data, padding, algorithm): pass def public_key(self): return self def signer(self, padding, algorithm): pass def decrypt(self, ciphertext, padding): pass def sign(self, data, padding, algorithm): value = hashlib.sha256(data).digest() res = self.crypto_client.sign(SignatureAlgorithm.rs256, digest=value) return res.signature
def __init__(self): # DefaultAzureCredential() expects the following environment variables: # * AZURE_CLIENT_ID # * AZURE_CLIENT_SECRET # * AZURE_TENANT_ID credential = DefaultAzureCredential() self.key_client = KeyClient(vault_url=os.environ["AZURE_PROJECT_URL"], credential=credential) self.key_name = "key-name-" + uuid.uuid1().hex
def __init__(self, arguments): super().__init__(arguments) # Auth configuration self.credential = EnvironmentCredential() self.async_credential = AsyncEnvironmentCredential() # Create clients vault_url = self.get_from_env("AZURE_KEYVAULT_URL") self.client = KeyClient(vault_url, self.credential) self.async_client = AsyncKeyClient(vault_url, self.async_credential)
def __init__(self): # DefaultAzureCredential() expects the following environment variables: # * AZURE_CLIENT_ID # * AZURE_CLIENT_SECRET # * AZURE_TENANT_ID authority_host = os.environ.get( 'AZURE_AUTHORITY_HOST') or KnownAuthorities.AZURE_PUBLIC_CLOUD credential = DefaultAzureCredential(authority=authority_host) self.key_client = KeyClient(vault_url=os.environ["AZURE_PROJECT_URL"], credential=credential) self.key_name = "key-name-" + uuid.uuid1().hex
def main(): try: # Enable logging enable_logging() # Setup some sample data sample_data = { "value1": "some value 1", "value2": "some value 2", "value3": "some value 3", "value4": "some value 4" } # Convert the dict to string, encode to bytes, and hash the data sample_data_hash = hashlib.sha512( json.dumps(sample_data).encode('UTF-8')).digest() # Obtain a credential from the system-assigned managed identity msi_credential = DefaultAzureCredential() # Get the key from Key Vault and setup a cryptography client key_client = KeyClient(KEY_VAULT_URL, msi_credential) key = key_client.get_key(CERTIFICATE_NAME) crypto_client = CryptographyClient(key, credential=msi_credential) # Use Key Vault to calculate a signature using RSASSA-PKCS1-v1_5 using SHA-512 data_signature = (crypto_client.sign(SignatureAlgorithm.rs512, sample_data_hash)).signature # Retrieve the certificate from Key Vault cert_client = CertificateClient(KEY_VAULT_URL, msi_credential) result = (cert_client.get_certificate(CERTIFICATE_NAME)).cer # Load the DER certificate returned into an x509 object and get the public key cert = load_der_x509_certificate(result, backend=default_backend()) public_key = cert.public_key() # Verify the signature try: public_key.verify(signature=data_signature, data=(json.dumps(sample_data)).encode('UTF-8'), padding=padding.PKCS1v15(), algorithm=hashes.SHA512()) logging.info('Payload verified successfully') print('Payload verified successfully!') except InvalidSignature: print('Payload and/or signature files failed verification') except Exception: logging.error('Execution error: ', exc_info=True)
def __init__(self, arguments): super().__init__(arguments) # Auth configuration self.credential = DefaultAzureCredential() self.async_credential = AsyncDefaultAzureCredential() # Create clients vault_url = self.get_from_env("AZURE_KEYVAULT_URL") self.client = KeyClient(vault_url, self.credential, **self._client_kwargs) self.async_client = AsyncKeyClient(vault_url, self.async_credential, **self._client_kwargs) self.key_name = "livekvtestgetkeyperfkey"
def run_sample(): # Instantiate a key client that will be used to call the service. # Notice that the client is using default Azure credentials. # To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID', # 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials. VAULT_URL = os.environ["VAULT_URL"] credential = DefaultAzureCredential() client = KeyClient(vault_url=VAULT_URL, credential=credential) try: # Let's create keys with RSA and EC type. If the key # already exists in the Key Vault, then a new version of the key is created. print("\n1. Create Key") rsa_key = client.create_rsa_key("rsaKeyName", hsm=False) ec_key = client.create_ec_key("ecKeyName", hsm=False) print("Key with name '{0}' was created of type '{1}'.".format(rsa_key.name, rsa_key.key_material.kty)) print("Key with name '{0}' was created of type '{1}'.".format(ec_key.name, ec_key.key_material.kty)) # The ec key is no longer needed. Need to delete it from the Key Vault. print("\n2. Delete a Key") key = client.delete_key(rsa_key.name) time.sleep(20) print("Key with name '{0}' was deleted on date {1}.".format(key.name, key.deleted_date)) # We accidentally deleted the rsa key. Let's recover it. # A deleted key can only be recovered if the Key Vault is soft-delete enabled. print("\n3. Recover Deleted Key") recovered_key = client.recover_deleted_key(rsa_key.name) print("Recovered Key with name '{0}'.".format(recovered_key.name)) # Let's delete ec key now. # If the keyvault is soft-delete enabled, then for permanent deletion deleted key needs to be purged. client.delete_key(ec_key.name) # To ensure key is deleted on the server side. print("\nDeleting EC Key...") time.sleep(20) # To ensure permanent deletion, we might need to purge the key. print("\n4. Purge Deleted Key") client.purge_deleted_key(ec_key.name) print("EC Key has been permanently deleted.") except HttpResponseError as e: if "(NotSupported)" in e.message: print("\n{0} Please enable soft delete on Key Vault to perform this operation.".format(e.message)) else: print("\nrun_sample has caught an error. {0}".format(e.message)) finally: print("\nrun_sample done")
def create_key(self, group_name, location, key_vault, tenant_id, object_id): if self.is_live: result = self.keyvault_client.vaults.begin_create_or_update( group_name, key_vault, { 'location': location, 'properties': { 'sku': { 'family': "A", 'name': 'standard' }, 'tenant_id': tenant_id, "access_policies": [{ "tenant_id": tenant_id, "object_id": object_id, "permissions": { "keys": [ "encrypt", "decrypt", "wrapKey", "unwrapKey", "sign", "verify", "get", "list", "create", "update", "import", "delete", "backup", "restore", "recover", "purge" ] } }], 'enabled_for_disk_encryption': True, } }).result() vault_url = result.properties.vault_uri vault_id = result.id from azure.keyvault.keys import KeyClient credentials = self.settings.get_azure_core_credentials() key_client = KeyClient(vault_url, credentials) # [START create_key] from dateutil import parser as date_parse expires_on = date_parse.parse("2050-02-02T08:00:00.000Z") key = key_client.create_key("testkey", "RSA", size=2048, expires_on=expires_on) return (vault_id, key.id) else: return ('000', '000')
def __init__(self, vault_endpoint, credential, transport=None, api_version=None, **kwargs): # type: (str, TokenCredential, Optional[HttpTransport], Optional[str], **Any) -> None super(VaultClient, self).__init__( vault_endpoint, credential, transport=transport, api_version=api_version, **kwargs ) self._credential = credential self._keys = KeyClient(self.vault_endpoint, credential, generated_client=self._client, **kwargs)
def __init__(self, vault_url, credential, transport=None, api_version=None, is_live=True, **kwargs): # type: (str, TokenCredential, Optional[HttpTransport], Optional[str], **Any) -> None super(VaultClient, self).__init__(vault_url, credential, transport=transport, api_version=api_version, **kwargs) self._credential = credential self._keys = KeyClient(self.vault_url, credential, generated_client=self._client, **kwargs) if not is_live: # ensure pollers don't sleep during playback for attr in dir(self._keys): if attr.startswith("begin_"): fn = getattr(self._keys, attr) wrapper = functools.partial(fn, _polling_interval=0) setattr(self._keys, attr, wrapper)
def test_custom_hook_policy(): class CustomHookPolicy(SansIOHTTPPolicy): pass client = KeyClient("...", object(), custom_hook_policy=CustomHookPolicy()) assert isinstance(client._client._config.custom_hook_policy, CustomHookPolicy)
def test_unsupported_version(): """When given an unsupported API version, the client should raise an error listing supported versions""" with pytest.raises(NotImplementedError) as ex: client = KeyClient("https://localhost", credential=object(), api_version="nonsense") assert all(version.value in str(ex.value) for version in ApiVersion)
def test_service_headers_allowed_in_logs(): service_headers = { "x-ms-keyvault-network-info", "x-ms-keyvault-region", "x-ms-keyvault-service-version" } client = KeyClient("...", object()) assert service_headers.issubset( client._client._config.http_logging_policy.allowed_header_names)
def __init__(self, credentials, vault_url: str, key_name: str): self.vault_url = vault_url self.key_name = key_name self.key_client = KeyClient(vault_url=vault_url, credential=credentials) try: self.kv_key = self.key_client.get_key(key_name) logger.info('Using existing user key from KeyVault') except ResourceNotFoundError: logger.info('Creating new user key in KeyVault') self.kv_key = self.key_client.create_rsa_key(key_name, size=self.key_size) self.crypto_client = CryptographyClient(self.kv_key, credential=credentials)
class KeyVaultKeys: def __init__(self): # DefaultAzureCredential() expects the following environment variables: # * AZURE_CLIENT_ID # * AZURE_CLIENT_SECRET # * AZURE_TENANT_ID authority_host = os.environ.get( 'AZURE_AUTHORITY_HOST') or KnownAuthorities.AZURE_PUBLIC_CLOUD credential = DefaultAzureCredential(authority=authority_host) self.key_client = KeyClient(vault_url=os.environ["AZURE_PROJECT_URL"], credential=credential) self.key_name = "key-name-" + uuid.uuid1().hex def create_rsa_key(self): print("Creating an RSA key...") self.key_client.create_rsa_key(name=self.key_name, size=2048) print("\tdone") def get_key(self): print("Getting a key...") key = self.key_client.get_key(name=self.key_name) print("\tdone, key: {}.".format(key.name)) def delete_key(self): print("Deleting a key...") deleted_key = self.key_client.begin_delete_key( name=self.key_name).result() print("\tdone: " + deleted_key.name) def run(self): print("") print("------------------------") print("Key Vault - Keys\nIdentity - Credential") print("------------------------") print("1) Create a key") print("2) Get that key") print("3) Delete that key (Clean up the resource)") print("") try: self.create_rsa_key() self.get_key() finally: self.delete_key()
def run(self, args): """Run the remediation job. :param args: List of arguments provided to the job. :type args: list. :returns: int """ params = self.parse(args[1]) client_id = os.environ.get("AZURE_CLIENT_ID") client_secret = os.environ.get("AZURE_CLIENT_SECRET") tenant_id = os.environ.get("AZURE_TENANT_ID") key_vault_name = params["key_vault_name"] # credential for Key Vault management client credential = ClientSecretCredential( client_id=client_id, client_secret=client_secret, tenant_id=tenant_id, ) # credential for AzureGraphRbacManagementClient credentials = ServicePrincipalCredentials( client_id=client_id, secret=client_secret, tenant=tenant_id, resource="https://graph.windows.net", ) keyvault_client = KeyVaultManagementClient(credential, params["subscription_id"]) graph_client = GraphRbacManagementClient(credentials, tenant_id, base_url=None) key_client = KeyClient( vault_url=f"https://{key_vault_name}.vault.azure.net/", credential=credential, ) client_authorization = AuthorizationManagementClient( credential, params["subscription_id"], api_version="2018-01-01-preview") return self.remediate( tenant_id, client_id, key_client, keyvault_client, graph_client, client_authorization, params["resource_group_name"], params["key_vault_name"], params["key_name"], params["subscription_id"], )
class KeyVaultKeys: def __init__(self): # DefaultAzureCredential() expects the following environment variables: # * AZURE_CLIENT_ID # * AZURE_CLIENT_SECRET # * AZURE_TENANT_ID credential = DefaultAzureCredential() self.key_client = KeyClient(vault_url=os.environ["AZURE_PROJECT_URL"], credential=credential) self.key_name = "key-name-" + uuid.uuid1().hex def create_rsa_key(self): print("Creating an RSA key...") self.key_client.create_rsa_key(name=self.key_name, size=2048, hsm=False) print("\tdone") def get_key(self): print("Getting a key...") key = self.key_client.get_key(name=self.key_name) print("\tdone, key: %s." % key.name) def delete_key(self): print("Deleting a key...") deleted_key = self.key_client.delete_key(name=self.key_name) print("\tdone: " + deleted_key.name) def run(self): print("") print("------------------------") print("Key Vault - Keys\nIdentity - Credential") print("------------------------") print("1) Create a key") print("2) Get that key") print("3) Delete that key (Clean up the resource)") print("") try: self.create_rsa_key() self.get_key() finally: self.delete_key()
def test_create_key_client(): vault_url = "vault_url" # pylint:disable=unused-variable # [START create_key_client] from azure.identity import DefaultAzureCredential from azure.keyvault.keys import KeyClient # Create a KeyClient using default Azure credentials credential = DefaultAzureCredential() key_client = KeyClient(vault_url, credential)
def test_key_client_context_manager(): transport = mock.MagicMock() client = KeyClient(vault_url="https://localhost", credential=object(), transport=transport) with client: assert transport.__enter__.call_count == 1 assert transport.__enter__.call_count == 1 assert transport.__exit__.call_count == 1
def data_plane_azure_keyvault_key_client(cli_ctx, command_args): from azure.keyvault.keys import KeyClient vault_url, credential, version = _prepare_data_plane_azure_keyvault_client( cli_ctx, command_args, ResourceType.DATA_KEYVAULT_KEYS) command_args.pop('hsm_name', None) command_args.pop('vault_base_url', None) command_args.pop('identifier', None) return KeyClient(vault_url=vault_url, credential=credential, api_version=version)
class GetKeyTest(PerfStressTest): def __init__(self, arguments): super().__init__(arguments) # Auth configuration self.credential = DefaultAzureCredential() self.async_credential = AsyncDefaultAzureCredential() # Create clients vault_url = self.get_from_env("AZURE_KEYVAULT_URL") self.client = KeyClient(vault_url, self.credential, **self._client_kwargs) self.async_client = AsyncKeyClient(vault_url, self.async_credential, **self._client_kwargs) self.key_name = "livekvtestgetkeyperfkey" async def global_setup(self): """The global setup is run only once.""" await super().global_setup() await self.async_client.create_rsa_key(self.key_name) async def global_cleanup(self): """The global cleanup is run only once.""" await self.async_client.delete_key(self.key_name) await self.async_client.purge_deleted_key(self.key_name) await super().global_cleanup() async def close(self): """This is run after cleanup.""" await self.async_client.close() await self.async_credential.close() await super().close() def run_sync(self): """The synchronous perf test.""" self.client.get_key(self.key_name) async def run_async(self): """The asynchronous perf test.""" await self.async_client.get_key(self.key_name)
def data_plane_azure_keyvault_key_client(cli_ctx, command_args): from azure.keyvault.keys import KeyClient vault_url, credential, version = _prepare_data_plane_azure_keyvault_client( cli_ctx, command_args, ResourceType.DATA_KEYVAULT_KEYS) command_args.pop('hsm_name', None) command_args.pop('vault_base_url', None) command_args.pop('identifier', None) api_version = '7.3-preview' if not is_azure_stack_profile( cmd=None, cli_ctx=cli_ctx) else '2016-10-01' return KeyClient(vault_url=vault_url, credential=credential, api_version=api_version or version)