Beispiel #1
0
    def __init__(self,
                 project_id: str = None,
                 location_id: str = None,
                 key_ring_id: str = None,
                 crypto_key_id: str = None,
                 key_name: str = None,
                 credential_path: str = None):
        """
        init
        :param project_id: GCP project id
        :param location_id: key location id ("global" etc.)
        :param key_ring_id: key ring id
        :param crypto_key_id: crypt key
        :param key_name: full path of key like below,
            'projects/(\S+)/locations/(\S+)/keyRings/(\S+)/cryptoKeys/(\S+)'
        :param credential_path: credential file path for a service account
        """
        if credential_path is not None:
            credentials = service_account.Credentials.from_service_account_file(
                credential_path)
        else:
            credentials = None

        if key_name is not None:
            self.__name = key_name
            ids = re.findall(
                'projects/(\S+)/locations/(\S+)/keyRings/(\S+)/cryptoKeys/(\S+)',
                key_name)
            if len(ids) != 1:
                raise ValueError("Failed to parse key name")
            else:
                ids = ids[0]
            if len(ids) != 4:
                raise ValueError("Failed to parse key name")
            self.__project_id = ids[0]
            self.__location_id = ids[1]
            self.__key_ring_id = ids[2]
            self.__crypto_key_id = ids[3]
            self.__client = kms.KeyManagementServiceClient(
                credentials=credentials)
        else:
            self.__project_id = project_id
            self.__location_id = location_id
            self.__key_ring_id = key_ring_id
            self.__crypto_key_id = crypto_key_id
            self.__client = kms.KeyManagementServiceClient(
                credentials=credentials)
            self.__update_key_name()
def update_key_set_primary(project_id, location_id, key_ring_id, key_id,
                           version_id):
    """
    Update the primary version of a key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        version_id (string): ID of the key to make primary (e.g. '2').

    Returns:
        CryptoKey: Updated Cloud KMS key.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key name.
    key_name = client.crypto_key_path(project_id, location_id, key_ring_id,
                                      key_id)

    # Call the API.
    updated_key = client.update_crypto_key_primary_version(
        request={
            'name': key_name,
            'crypto_key_version_id': version_id
        })
    print('Updated {} primary to {}'.format(updated_key.name, version_id))
    return updated_key
def destroy_key_version(project_id, location_id, key_ring_id, key_id,
                        version_id):
    """
    Schedule destruction of the given key version.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        version_id (string): ID of the key version to destroy (e.g. '1').

    Returns:
        CryptoKeyVersion: The version.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key version name.
    key_version_name = client.crypto_key_version_path(project_id, location_id,
                                                      key_ring_id, key_id,
                                                      version_id)

    # Call the API.
    destroyed_version = client.destroy_crypto_key_version(
        request={'name': key_version_name})
    print('Destroyed key version: {}'.format(destroyed_version.name))
    return destroyed_version
Beispiel #4
0
def encrypt_symmetric(plaintext, project_id='prueba-tecnica-295209', location_id='global', key_ring_id='prueba', key_id='clave'):
    """
    Encrypt plaintext using a symmetric key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        plaintext (string): message to encrypt

    Returns:
        bytes: Encrypted ciphertext.

    """

    # Import base64 for printing the ciphertext.
    import base64

    # Convert the plaintext to bytes.
    plaintext_bytes = plaintext.encode('utf-8')

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key name.
    key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)

    # Call the API.
    encrypt_response = client.encrypt(request={'name': key_name, 'plaintext': plaintext_bytes})
    #print('Ciphertext: {}'.format(base64.b64encode(encrypt_response.ciphertext)))
    return encrypt_response
def kms_encrypt_decrypt_cursor(cursor, kms_type):
    if cursor and hasattr(config, 'KMS_KEY_INFO') and \
            'keyring' in config.KMS_KEY_INFO and \
            'key' in config.KMS_KEY_INFO and \
            'location' in config.KMS_KEY_INFO:
        project_id = os.environ['GOOGLE_CLOUD_PROJECT']
        location_id = config.KMS_KEY_INFO['location']
        key_ring_id = config.KMS_KEY_INFO['keyring']
        crypto_key_id = config.KMS_KEY_INFO['key']

        try:
            client = kms.KeyManagementServiceClient()
            name = client.crypto_key_path_path(project_id, location_id,
                                               key_ring_id, crypto_key_id)

            if kms_type == 'encrypt':
                encrypt_response = client.encrypt(
                    name,
                    cursor.encode() if isinstance(cursor, str) else cursor)
                response = base64.urlsafe_b64encode(
                    encrypt_response.ciphertext).decode()
            else:
                encrypt_response = client.decrypt(
                    name, base64.urlsafe_b64decode(cursor))
                response = encrypt_response.plaintext
        except Exception as e:
            logging.error(
                f"An exception occurred when {kms_type}-ing a cursor: {str(e)}"
            )
            return None
    else:
        response = cursor

    return response
Beispiel #6
0
def get_public_key(project_id, location_id, key_ring_id, key_id, version_id):
    """
    Get the public key for an asymmetric key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        version_id (string): ID of the key to use (e.g. '1').

    Returns:
        PublicKey: Cloud KMS public key response.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key version name.
    key_version_name = client.crypto_key_version_path(project_id, location_id,
                                                      key_ring_id, key_id,
                                                      version_id)

    # Call the API.
    public_key = client.get_public_key(request={'name': key_version_name})
    print('Public key: {}'.format(public_key.pem))
    return public_key
Beispiel #7
0
def restore_key_version(project_id, location_id, key_ring_id, key_id, version_id):
    """
    Restore a key version scheduled for destruction.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        version_id (string): ID of the version to use (e.g. '1').

    Returns:
        CryptoKeyVersion: Restored Cloud KMS key version.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key version name.
    key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, version_id)

    # Call the API.
    restored_version = client.restore_crypto_key_version(key_version_name)
    print('Restored key version: {}'.format(restored_version.name))
    return restored_version
def decrypt_symmetric(project_id, location_id, key_ring_id, key_id,
                      ciphertext):
    """
    Decrypt the ciphertext using the symmetric key

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        ciphertext (bytes): Encrypted bytes to decrypt.

    Returns:
        DecryptResponse: Response including plaintext.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key name.
    key_name = client.crypto_key_path(project_id, location_id, key_ring_id,
                                      key_id)

    # Call the API.
    decrypt_response = client.decrypt(request={
        'name': key_name,
        'ciphertext': ciphertext
    })
    print('Plaintext: {}'.format(decrypt_response.plaintext))
    return decrypt_response
Beispiel #9
0
def create_key_ring(project_id, location_id, id):
    """
    Creates a new key ring in Cloud KMS

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        id (string): ID of the key ring to create (e.g. 'my-key-ring').

    Returns:
        KeyRing: Cloud KMS key ring.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the parent location name.
    location_name = f'projects/{project_id}/locations/{location_id}'

    # Build the key ring.
    key_ring = {}

    # Call the API.
    created_key_ring = client.create_key_ring(request={'parent': location_name, 'key_ring_id': id, 'key_ring': key_ring})
    print('Created key ring: {}'.format(created_key_ring.name))
    return created_key_ring
Beispiel #10
0
def check_state_imported_key(project_id, location_id, key_ring_id,
                             import_job_id):
    """
    Check the state of an import job in Cloud KMS.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        import_job_id (string): ID of the import job (e.g. 'my-import-job').
    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Retrieve the fully-qualified import_job string.
    import_job_name = client.import_job_path(project_id, location_id,
                                             key_ring_id, import_job_id)

    # Retrieve the state from an existing import job.
    import_job = client.get_import_job(name=import_job_name)

    print('Current state of import job {}: {}'.format(import_job.name,
                                                      import_job.state))
Beispiel #11
0
 def _ensure_init(self):
   if self._fernet is None:
     kms_client = kms.KeyManagementServiceClient()
     fernet_key = kms_client.decrypt(self._KMS_KEY_PATH,
                                     base64.b64decode(self._ENCRYPTED_KEY))
     self._key = fernet_key.plaintext
     self._fernet = Fernet(self._key.decode('utf-8'))
Beispiel #12
0
 def kms_client(self):
     # credentials
     credentials = None
     if self.credentials_file:
         credentials = service_account.Credentials.from_service_account_file(self.credentials_file)
         credentials = credentials.with_scopes(["https://www.googleapis.com/auth/cloudkms"])
     return kms.KeyManagementServiceClient(credentials=credentials)
def kms_encrypt_decrypt_cursor(cursor, process):
    if cursor:
        project_id = os.environ["GOOGLE_CLOUD_PROJECT"]
        location_id = "europe"
        key_ring_id = f"{project_id}-keyring"
        crypto_key_id = "db-cursor-key"

        try:
            client = kms.KeyManagementServiceClient()
            name = client.crypto_key_path(project_id, location_id, key_ring_id,
                                          crypto_key_id)

            if process == "encrypt":
                text = cursor.encode() if isinstance(cursor, str) else cursor
                encrypt_response = client.encrypt(name=name, plaintext=text)
                response = base64.urlsafe_b64encode(
                    encrypt_response.ciphertext).decode()
            else:
                text = base64.urlsafe_b64decode(cursor)
                encrypt_response = client.decrypt(name=name, ciphertext=text)
                response = encrypt_response.plaintext
        except Exception as e:
            logging.error(
                f"An exception occurred when {process}-ing a cursor: {str(e)}")
            return None
    else:
        response = None

    return response
Beispiel #14
0
def create_key_version(project_id, location_id, key_ring_id, key_id):
    """
    Creates a new version of the given key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key for which to create a new version (e.g. 'my-key').

    Returns:
        CryptoKeyVersion: Cloud KMS key version.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the parent key name.
    key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)

    # Build the key version.
    version = {}

    # Call the API.
    created_version = client.create_crypto_key_version(key_name, version)
    print('Created key version: {}'.format(created_version.name))
    return created_version
Beispiel #15
0
def get_key_labels(project_id, location_id, key_ring_id, key_id):
    """
    Get a key and its labels.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').

    Returns:
        CryptoKey: Cloud KMS key.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key name.
    key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)

    # Call the API.
    key = client.get_crypto_key(request={'name': key_name})

    # Example of iterating over labels.
    for k, v in key.labels.items():
        print('{} = {}'.format(k, v))

    return key
Beispiel #16
0
def encrypt_symmetric(project_id, location_id, key_ring_id, key_id, plaintext):
    """
    Encrypt plaintext using a symmetric key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        plaintext (string): message to encrypt

    Returns:
        bytes: Encrypted ciphertext.

    """

    # Import the client library.
    from google.cloud import kms

    # Import base64 for printing the ciphertext.
    import base64

    # Convert the plaintext to bytes.
    plaintext_bytes = plaintext.encode('utf-8')

    # Optional, but recommended: compute plaintext's CRC32C.
    # See crc32c() function defined below.
    plaintext_crc32c = crc32c(plaintext_bytes)

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key name.
    key_name = client.crypto_key_path(project_id, location_id, key_ring_id,
                                      key_id)

    # Call the API.
    encrypt_response = client.encrypt(
        request={
            'name': key_name,
            'plaintext': plaintext_bytes,
            'plaintext_crc32c': plaintext_crc32c
        })

    # Optional, but recommended: perform integrity verification on encrypt_response.
    # For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
    # https://cloud.google.com/kms/docs/data-integrity-guidelines
    if not encrypt_response.verified_plaintext_crc32c:
        raise Exception(
            'The request sent to the server was corrupted in-transit.')
    if not encrypt_response.ciphertext_crc32c == crc32c(
            encrypt_response.ciphertext):
        raise Exception(
            'The response received from the server was corrupted in-transit.')
    # End integrity verification

    print('Ciphertext: {}'.format(base64.b64encode(
        encrypt_response.ciphertext)))
    return encrypt_response
Beispiel #17
0
def verify_asymmetric_ec(project_id, location_id, key_ring_id, key_id,
                         version_id, message, signature):
    """
    Verify the signature of an message signed with an asymmetric EC key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        version_id (string): ID of the version to use (e.g. '1').
        message (string): Original message (e.g. 'my message')
        signature (bytes): Signature from a sign request.

    Returns:
        bool: True if verified, False otherwise

    """

    # Import the client library.
    from google.cloud import kms

    # Import cryptographic helpers from the cryptography package.
    from cryptography.exceptions import InvalidSignature
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes, serialization
    from cryptography.hazmat.primitives.asymmetric import ec, utils

    # Import hashlib.
    import hashlib

    # Convert the message to bytes.
    message_bytes = message.encode('utf-8')

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key version name.
    key_version_name = client.crypto_key_version_path(project_id, location_id,
                                                      key_ring_id, key_id,
                                                      version_id)

    # Get the public key.
    public_key = client.get_public_key(key_version_name)

    # Extract and parse the public key as a PEM-encoded RSA key.
    pem = public_key.pem.encode('utf-8')
    ec_key = serialization.load_pem_public_key(pem, default_backend())
    hash_ = hashlib.sha256(message_bytes).digest()

    # Attempt to verify.
    try:
        sha256 = hashes.SHA256()
        ec_key.verify(signature, hash_, ec.ECDSA(utils.Prehashed(sha256)))
        print('Signature verified')
        return True
    except InvalidSignature:
        print('Signature failed to verify')
        return False
Beispiel #18
0
    def __init__(self):
        # This facade is currently using both libraries as the Cloud Client library doesn't support locations

        # Cloud Client
        client_info = ClientInfo(user_agent=get_user_agent())
        self.cloud_client = kms.KeyManagementServiceClient(client_info=client_info)
        # self.cloud_client = kms.KeyManagementServiceClient()

        super().__init__('cloudkms', 'v1')  # API Client
Beispiel #19
0
def encrypt_asymmetric(project_id, location_id, key_ring_id, key_id,
                       version_id, plaintext):
    """
    Encrypt plaintext using the public key portion of an asymmetric key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        version_id (string): ID of the key version to use (e.g. '1').
        plaintext (string): message to encrypt

    Returns:
        bytes: Encrypted ciphertext.

    """

    # Import the client library.
    from google.cloud import kms

    # Import base64 for printing the ciphertext.
    import base64

    # Import cryptographic helpers from the cryptography package.
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes, serialization
    from cryptography.hazmat.primitives.asymmetric import padding

    # Convert the plaintext to bytes.
    plaintext_bytes = plaintext.encode('utf-8')

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key version name.
    key_version_name = client.crypto_key_version_path(project_id, location_id,
                                                      key_ring_id, key_id,
                                                      version_id)

    # Get the public key.
    public_key = client.get_public_key(request={'name': key_version_name})

    # Extract and parse the public key as a PEM-encoded RSA key.
    pem = public_key.pem.encode('utf-8')
    rsa_key = serialization.load_pem_public_key(pem, default_backend())

    # Construct the padding. Note that the padding differs based on key choice.
    sha256 = hashes.SHA256()
    mgf = padding.MGF1(algorithm=sha256)
    pad = padding.OAEP(mgf=mgf, algorithm=sha256, label=None)

    # Encrypt the data using the public key.
    ciphertext = rsa_key.encrypt(plaintext_bytes, pad)
    print('Ciphertext: {}'.format(base64.b64encode(ciphertext)))
    return ciphertext
def decrypt_asymmetric(project_id, location_id, key_ring_id, key_id,
                       version_id, ciphertext):
    """
    Decrypt the ciphertext using an asymmetric key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        version_id (string): ID of the key version to use (e.g. '1').
        ciphertext (bytes): Encrypted bytes to decrypt.

    Returns:
        DecryptResponse: Response including plaintext.

    """

    # Import the client library.
    from google.cloud import kms

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key version name.
    key_version_name = client.crypto_key_version_path(project_id, location_id,
                                                      key_ring_id, key_id,
                                                      version_id)

    # Optional, but recommended: compute ciphertext's CRC32C.
    # See crc32c() function defined below.
    ciphertext_crc32c = crc32c(ciphertext)

    # Call the API.
    decrypt_response = client.asymmetric_decrypt(
        request={
            'name': key_version_name,
            'ciphertext': ciphertext,
            'ciphertext_crc32c': ciphertext_crc32c
        })

    # Optional, but recommended: perform integrity verification on decrypt_response.
    # For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
    # https://cloud.google.com/kms/docs/data-integrity-guidelines
    if not decrypt_response.verified_ciphertext_crc32c:
        raise Exception(
            'The request sent to the server was corrupted in-transit.')
    if not decrypt_response.plaintext_crc32c == crc32c(
            decrypt_response.plaintext):
        raise Exception(
            'The response received from the server was corrupted in-transit.')
    # End integrity verification

    print('Plaintext: {}'.format(decrypt_response.plaintext))
    return decrypt_response
def create_key_rotation_schedule(project_id, location_id, key_ring_id, id):
    """
    Creates a new key in Cloud KMS that automatically rotates.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        id (string): ID of the key to create (e.g. 'my-rotating-key').

    Returns:
        CryptoKey: Cloud KMS key.

    """

    # Import the client library.
    from google.cloud import kms

    # Import time for getting the current time.
    import time

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the parent key ring name.
    key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)

    # Build the key.
    purpose = kms.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT
    algorithm = kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION
    key = {
        'purpose': purpose,
        'version_template': {
            'algorithm': algorithm,
        },

        # Rotate the key every 30 days.
        'rotation_period': {
            'seconds': 60 * 60 * 24 * 30
        },

        # Start the first rotation in 24 hours.
        'next_rotation_time': {
            'seconds': int(time.time()) + 60 * 60 * 24
        }
    }

    # Call the API.
    created_key = client.create_crypto_key(request={
        'parent': key_ring_name,
        'crypto_key_id': id,
        'crypto_key': key
    })
    print('Created labeled key: {}'.format(created_key.name))
    return created_key
Beispiel #22
0
def encrypt(project, location, keyring, cryptokey,  # pylint: disable=too-many-arguments
            bucket, target, secret_name):
    unversioned_key = get_unversioned_key(project, location,
                                          keyring, cryptokey)
    kms_client = kms.KeyManagementServiceClient()
    versioned_key = kms_client.get_crypto_key(unversioned_key).primary.name

    with open_file(secret_name) as secret_file:
        unencrypted = secret_file.read()

    encrypted = encrypt_secret(versioned_key, unencrypted, client=kms_client)
    save_secret(project, bucket, target, encrypted, unversioned_key)
Beispiel #23
0
def reencrypt(project, bucket, target):
    storage_client = storage.Client(project=project)
    secret = get_secret(project, bucket, target, client=storage_client)
    encrypted = secret['secret']
    key = secret['key']

    kms_client = kms.KeyManagementServiceClient()
    primary_key = kms_client.get_crypto_key(key).primary.name

    decrypted = decrypt_secret(key, encrypted, client=kms_client)
    encrypted = encrypt_secret(primary_key, decrypted, client=kms_client)
    save_secret(project, bucket, target, encrypted, key, client=storage_client)
Beispiel #24
0
def create_key_hsm(project_id, location_id, key_ring_id, id):
    """
    Creates a new key in Cloud KMS backed by Cloud HSM.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        id (string): ID of the key to create (e.g. 'my-hsm-key').

    Returns:
        CryptoKey: Cloud KMS key.

    """

    # Import the client library.
    from google.cloud import kms
    from google.protobuf import duration_pb2
    import datetime

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the parent key ring name.
    key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)

    # Build the key.
    purpose = kms.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT
    algorithm = kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION
    protection_level = kms.ProtectionLevel.HSM
    key = {
        'purpose':
        purpose,
        'version_template': {
            'algorithm': algorithm,
            'protection_level': protection_level
        },

        # Optional: customize how long key versions should be kept before
        # destroying.
        'destroy_scheduled_duration':
        duration_pb2.Duration().FromTimedelta(datetime.timedelta(days=1))
    }

    # Call the API.
    created_key = client.create_crypto_key(request={
        'parent': key_ring_name,
        'crypto_key_id': id,
        'crypto_key': key
    })
    print('Created hsm key: {}'.format(created_key.name))
    return created_key
Beispiel #25
0
def create_key_asymmetric_sign(project_id, location_id, key_ring_id, id):
    """
    Creates a new asymmetric signing key in Cloud KMS.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        id (string): ID of the key to create (e.g. 'my-asymmetric-signing-key').

    Returns:
        CryptoKey: Cloud KMS key.

    """

    # Import the client library.
    from google.cloud import kms
    from google.protobuf import duration_pb2
    import datetime

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the parent key ring name.
    key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)

    # Build the key.
    purpose = kms.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_SIGN
    algorithm = kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.RSA_SIGN_PKCS1_2048_SHA256
    key = {
        'purpose':
        purpose,
        'version_template': {
            'algorithm': algorithm,
        },

        # Optional: customize how long key versions should be kept before
        # destroying.
        'destroy_scheduled_duration':
        duration_pb2.Duration().FromTimedelta(datetime.timedelta(days=1))
    }

    # Call the API.
    created_key = client.create_crypto_key(request={
        'parent': key_ring_name,
        'crypto_key_id': id,
        'crypto_key': key
    })
    print('Created asymmetric signing key: {}'.format(created_key.name))
    return created_key
    def create_key_ring(self, id):
        # Create the client.
        client = kms.KeyManagementServiceClient()

        # Build the parent location name.
        location_name = f'projects/{self.project_id}/locations/{self.location_id}'

        # Build the key ring.
        key_ring = {}

        # Call the API.
        created_key_ring = client.create_key_ring(
            request={'parent': location_name, 'key_ring_id': id, 'key_ring': key_ring})
        # print('Created key ring: {}'.format(created_key_ring.name))
        return created_key_ring
Beispiel #27
0
    def setUp(self):
        super(TestKMSIntegration, self).setUp()
        client = kms.KeyManagementServiceClient()
        project = Config.CLIENT.project
        location = self.bucket.location.lower()
        keyring_name = self.KEYRING_NAME
        purpose = kms.enums.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT

        # If the keyring doesn't exist create it.
        keyring_path = client.key_ring_path(project, location, keyring_name)

        try:
            client.get_key_ring(keyring_path)
        except exceptions.NotFound:
            parent = client.location_path(project, location)
            client.create_key_ring(parent, keyring_name, {})

            # Mark this service account as an owner of the new keyring
            service_account = Config.CLIENT.get_service_account_email()
            policy = {
                "bindings": [
                    {
                        "role": "roles/cloudkms.cryptoKeyEncrypterDecrypter",
                        "members": [
                            "serviceAccount:" + service_account,
                        ]
                    }
                ]
            }
            client.set_iam_policy(keyring_path, policy)

        # Populate the keyring with the keys we use in the tests
        key_names = [
            'gcs-test',
            'gcs-test-alternate',
            'explicit-kms-key-name',
            'default-kms-key-name',
            'override-default-kms-key-name',
            'alt-default-kms-key-name',
        ]
        for key_name in key_names:
            key_path = client.crypto_key_path(
                project, location, keyring_name, key_name)
            try:
                client.get_crypto_key(key_path)
            except exceptions.NotFound:
                key = {'purpose': purpose}
                client.create_crypto_key(keyring_path, key_name, key)
Beispiel #28
0
def sign_asymmetric(project_id, location_id, key_ring_id, key_id, version_id, message):
    """
    Sign a message using the public key part of an asymmetric key.

    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        key_id (string): ID of the key to use (e.g. 'my-key').
        version_id (string): Version to use (e.g. '1').
        message (string): Message to sign.

    Returns:
        AsymmetricSignResponse: Signature.

    """

    # Import the client library.
    from google.cloud import kms

    # Import base64 for printing the ciphertext.
    import base64

    # Import hashlib for calculating hashes.
    import hashlib

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key version name.
    key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, version_id)

    # Convert the message to bytes.
    message_bytes = message.encode('utf-8')

    # Calculate the hash.
    hash_ = hashlib.sha256(message_bytes).digest()

    # Build the digest.
    #
    # Note: Key algorithms will require a varying hash function. For
    # example, EC_SIGN_P384_SHA384 requires SHA-384.
    digest = {'sha256': hash_}

    # Call the API
    sign_response = client.asymmetric_sign(request={'name': key_version_name, 'digest': digest})
    print('Signature: {}'.format(base64.b64encode(sign_response.signature)))
    return sign_response
Beispiel #29
0
    def __init__(self, config, *args, **kwargs):
        super(GCPBackend, self).__init__(config)

        self.kms_client = kms.KeyManagementServiceClient()
        self.datastore_client = datastore.Client(
            project=config.get("datastore_project")
            or self._get_default_project(),
            namespace=config.get("datastore_namespace"),
        )

        self.datastore_kind = config.get("datastore_kind", "Secret")
        self.datastore_property_ciphertext = config.get(
            "datastore_property_ciphertext", "ciphertext")
        self.datastore_property_keyid = config.get("datastore_property_keyid",
                                                   "keyid")
        self.default_keyid = config.get("keyid") or self._get_default_keyid()
Beispiel #30
0
    def setUp(self):
        super(TestKMSIntegration, self).setUp()
        client = kms.KeyManagementServiceClient()

        # If the keyring doesn't exist create it.
        name = client.key_ring_path(Config.CLIENT.project,
                                    self.bucket.location.lower(),
                                    self.KEYRING_NAME)

        try:
            client.get_key_ring(name)
        except exceptions.NotFound:
            parent = client.location_path(Config.CLIENT.project,
                                          self.bucket.location.lower())
            client.create_key_ring(parent, self.KEYRING_NAME, {})

        # Ensure this service account is marked as an owner to the test keyring
        keyring_location_path = client.key_ring_path(
            Config.CLIENT.project, self.bucket.location.lower(),
            self.KEYRING_NAME)
        service_account = Config.CLIENT.get_service_account_email()
        policy = {
            "bindings": [{
                "role": "roles/owner",
                "members": [
                    "serviceAccount:" + service_account,
                ]
            }]
        }

        client.set_iam_policy(keyring_location_path, policy)

        # Populate the keyring with the keys we use in the tests
        for keyname in [
                'gcs-test', 'gcs-test-alternate', 'explicit-kms-key-name',
                'default-kms-key-name', 'override-default-kms-key-name',
                'alt-default-kms-key-name'
        ]:
            key_path = client.crypto_key_path(Config.CLIENT.project,
                                              self.bucket.location.lower(),
                                              self.KEYRING_NAME, keyname)
            try:
                client.get_crypto_key(key_path)
            except exceptions.NotFound:
                purpose = kms.enums.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT
                key = {'purpose': purpose}
                client.create_crypto_key(keyring_location_path, keyname, key)