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)
Example #2
0
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