def __init__(self, key_uri, creds, tmp_location=_TMP_LOCATION): """Init class for EncryptWithTink. Args: key_uri: string with the resource identifier for the KMS symmetric key creds: path to the creds.json file with the service account key for KMS tmp_location: temporary directory for encryption and decryption Returns: None """ self.tmp_location = tmp_location # Make the tmp dir if it doesn't exist if not os.path.isdir(self.tmp_location): # noinspection PyUnusedLocal try: os.makedirs(self.tmp_location) except FileExistsError: # This is ok because the directory already exists pass except OSError as os_error: error_and_exit(str(os_error)) # Initialize Tink try: aead.register() self.key_template = aead.aead_key_templates.AES128_EAX self.keyset_handle = tink.new_keyset_handle(self.key_template) gcp_client = gcpkms.GcpKmsClient(key_uri, creds) gcp_aead = gcp_client.get_aead(key_uri) self.env_aead = aead.KmsEnvelopeAead(self.key_template, gcp_aead) except TinkError as tink_init_error: error_and_exit('tink initialization failed: ' + str(tink_init_error))
def test_client_not_bound(self): gcp_key1 = 'gcp-kms://projects/someProject/.../cryptoKeys/key1' gcp_key2 = 'gcp-kms://projects/otherProject/.../cryptoKeys/key2' non_gcp_key = 'aws-kms://arn:aws:kms:us-west-2:acc:other/key3' gcp_client = gcpkms.GcpKmsClient('', CREDENTIAL_PATH) self.assertEqual(gcp_client.does_support(gcp_key1), True) self.assertEqual(gcp_client.does_support(gcp_key2), True) self.assertEqual(gcp_client.does_support(non_gcp_key), False)
def test_encrypt_decrypt(self): gcp_client = gcpkms.GcpKmsClient(KEY_URI, CREDENTIAL_PATH) aead = gcp_client.get_aead(KEY_URI) plaintext = b'helloworld' ciphertext = aead.encrypt(plaintext, b'') self.assertEqual(plaintext, aead.decrypt(ciphertext, b'')) plaintext = b'hello' associated_data = b'world' ciphertext = aead.encrypt(plaintext, associated_data) self.assertEqual(plaintext, aead.decrypt(ciphertext, associated_data))
def main(argv): if len(argv) != 6: raise app.UsageError( 'Expected 5 arguments, got %d.\n' 'Usage: %s gcp-credentials key-uri input-file output-file [decrypt]' % (len(argv) - 1, argv[0])) mode = argv[1] gcp_credentials = argv[2] key_uri = argv[3] input_file_path = argv[4] output_file_path = argv[5] # Initialise Tink. try: aead.register() except tink.TinkError as e: logging.error('Error initialising Tink: %s', e) return 1 # Read the GCP credentials and setup client try: gcp_client = gcpkms.GcpKmsClient(key_uri, gcp_credentials) gcp_aead = gcp_client.get_aead(key_uri) except tink.TinkError as e: logging.error('Error initializing GCP client: %s', e) return 1 # Create envelope AEAD primitive using AES256 GCM for encrypting the data try: key_template = aead.aead_key_templates.AES256_GCM env_aead = aead.KmsEnvelopeAead(key_template, gcp_aead) except tink.TinkError as e: logging.error('Error creating primitive: %s', e) return 1 with open(input_file_path, 'rb') as input_file: input_data = input_file.read() if mode == 'decrypt': output_data = env_aead.decrypt(input_data, b'envelope_example') elif mode == 'encrypt': output_data = env_aead.encrypt(input_data, b'envelope_example') else: logging.error( 'Error mode not supported. Please choose "encrypt" or "decrypt".' ) return 1 with open(output_file_path, 'wb') as output_file: output_file.write(output_data)
def test_corrupted_ciphertext(self): gcp_client = gcpkms.GcpKmsClient(KEY_URI, CREDENTIAL_PATH) aead = gcp_client.get_aead(KEY_URI) plaintext = b'helloworld' ciphertext = aead.encrypt(plaintext, b'') self.assertEqual(plaintext, aead.decrypt(ciphertext, b'')) # Corrupt each byte once and check that decryption fails # NOTE: Only starting at 4th byte here, as the 3rd byte is malleable # (see b/146633745). for byte_idx in range(3, len(ciphertext)): tmp_ciphertext = list(ciphertext) tmp_ciphertext[byte_idx] ^= 1 corrupted_ciphertext = bytes(tmp_ciphertext) with self.assertRaises(core.TinkError): aead.decrypt(corrupted_ciphertext, b'')
def init_tink_env_aead(key_uri: str, credentials: str) -> tink.aead.KmsEnvelopeAead: aead.register() try: gcp_client = gcpkms.GcpKmsClient(key_uri, credentials) gcp_aead = gcp_client.get_aead(key_uri) except tink.TinkError as e: logger.error("Error initializing GCP client: %s", e) raise e # Create envelope AEAD primitive using AES256 GCM for encrypting the data # This key should only be used for client-side encryption to ensure authenticity and integrity # of data. key_template = aead.aead_key_templates.AES256_GCM env_aead = aead.KmsEnvelopeAead(key_template, gcp_aead) print(f"Created envelope AEAD Primitive using KMS URI: {key_uri}") return env_aead
def __init__(self, encoded_key, key_uri=None): self.gcp_aead = None if key_uri != None: gcp_client = gcpkms.GcpKmsClient(key_uri=key_uri, credentials_path="") self.gcp_aead = gcp_client.get_aead(key_uri) if (encoded_key == None): self.keyset_handle = tink.new_keyset_handle( mac.mac_key_templates.HMAC_SHA256_256BITTAG) else: reader = tink.BinaryKeysetReader(base64.b64decode(encoded_key)) self.keyset_handle = tink.KeysetHandle.read( reader, self.gcp_aead) else: if (encoded_key == None): self.keyset_handle = tink.new_keyset_handle( mac.mac_key_templates.HMAC_SHA256_256BITTAG) else: reader = tink.BinaryKeysetReader(base64.b64decode(encoded_key)) self.keyset_handle = cleartext_keyset_handle.read(reader) self.mac = self.keyset_handle.primitive(mac.Mac)
def __init__(self, encoded_key, key_uri=None): self.gcp_aead = None if key_uri != None: gcp_client = gcpkms.GcpKmsClient(key_uri=key_uri, credentials_path="") self.gcp_aead = gcp_client.get_aead(key_uri) if (encoded_key == None): self.keyset_handle = tink.new_keyset_handle( aead.aead_key_templates.AES256_GCM) else: reader = tink.BinaryKeysetReader(base64.b64decode(encoded_key)) self.keyset_handle = tink.KeysetHandle.read( reader, self.gcp_aead) else: if (encoded_key == None): self.keyset_handle = tink.new_keyset_handle( aead.aead_key_templates.AES256_GCM) else: reader = tink.BinaryKeysetReader(base64.b64decode(encoded_key)) self.keyset_handle = cleartext_keyset_handle.read(reader) self.key = self.keyset_handle.keyset_info() self.aead_primitive = self.keyset_handle.primitive(aead.Aead)
def test_encrypt_with_bad_uri(self): with self.assertRaises(core.TinkError): gcp_client = gcpkms.GcpKmsClient(KEY_URI, CREDENTIAL_PATH) gcp_client.get_aead(BAD_KEY_URI)
def test_client_invalid_path(self): with self.assertRaises(ValueError): gcpkms.GcpKmsClient('', CREDENTIAL_PATH + 'corrupted')
def test_client_registration(self): gcp_client = gcpkms.GcpKmsClient('', CREDENTIAL_PATH) gcp_client.register_client('', CREDENTIAL_PATH)
def test_client_generation(self): gcp_client = gcpkms.GcpKmsClient('', CREDENTIAL_PATH) self.assertNotEqual(gcp_client, None)