client.create_key(_get_vault_url(), key_name, 'RSA') print('Created key vault key: ' + key_name) # create a random AES key to wrap to_wrap = os.urandom(16) print('\noriginal value:') print(to_wrap) # wrap the key wrapped = client.wrap_key(vault_base_url=_get_vault_url(), key_name=key_name, key_version='', algorithm='RSA-OAEP', value=to_wrap) print('\nwrap_key result:') print(wrapped.result) unwrapped = client.unwrap_key(vault_base_url=_get_vault_url(), key_name=key_name, key_version='', algorithm='RSA-OAEP', value=wrapped.result) # delete the key client.delete_key(_get_vault_url(), key_name) print('\nunwrap result:') print(unwrapped.result)
class AESKeyWrapper: """ Wrapper for key wrapping functions. Key is wrapped localy with public key retrieved from Azure KeyVault. Uses Azure KeyVault API to unwrap the key. """ def __init__(self, vault, client_id, secret, tenant, key_name, key_version): """ Wrapper constructor. :param str vault: Azure KeyVault url. :param str client_id: Azure Client Id. :param str secret: Azure Client secret. :param str tenant: Azure tenant id. :param str key_name: Azure KeyVault key name. :param str key_version: Azure KeyVault key version. """ self._key_name = key_name self._key_version = key_version self._vault = vault self._client_id = client_id self._secret = secret self._tenant = tenant self._credentials = ServicePrincipalCredentials( client_id=self._client_id, secret=self._secret, tenant=self._tenant) self.kvclient = KeyVaultClient(self._credentials) def wrap_aes_key_local(self, aes_key, public_key): """ Wraps AES key locally. Uses RSA-OAEP algorithm to wrap provided key. :param str aes_key: unencrypted AES key. :param str public_key: public part of RSA key. :return: String with encrypted AES key. """ int_n = self._bytes_to_int(public_key.n) int_e = self._bytes_to_int(public_key.e) public_numbers = RSAPublicNumbers(int_e, int_n) public_key = public_numbers.public_key(default_backend()) wrapped_key = public_key.encrypt( aes_key, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None)) return wrapped_key def unwrap_aes_key(self, wrapped_key): """ Unwraps AES key with Azure KeyVault. Uses RSA-OAEP algorithm to unwrap provided key. :param str wrapped_key: encrypted AES key. :return: String with unencrypted AES key. """ return self.kvclient.unwrap_key(self._vault, self._key_name, self._key_version, 'RSA-OAEP', wrapped_key).result def get_public_key(self): """ Retrieve public key from Azure KeyVault. :return: JsonWebKey with public RSA key. """ key_bundle = self.kvclient.get_key(self._vault, self._key_name, self._key_version) return key_bundle.key def _bytes_to_int(self, bytes): """ Helper function to convert bytes array to int. """ result = 0 for b in bytes: result = result * 256 + ord(b) return result