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_ciphertext_too_short(self): key_template = aead.aead_key_templates.AES256_GCM keyset_handle = tink.new_keyset_handle(key_template) remote_aead = keyset_handle.primitive(aead.Aead) env_aead = aead.KmsEnvelopeAead(key_template, remote_aead) with self.assertRaises(core.TinkError): env_aead.decrypt(b'foo', b'some ad')
def test_encrypt_decrypt(self): key_template = aead.aead_key_templates.AES256_GCM keyset_handle = tink.new_keyset_handle(key_template) remote_aead = keyset_handle.primitive(aead.Aead) env_aead = aead.KmsEnvelopeAead(key_template, remote_aead) plaintext = b'helloworld' ciphertext = env_aead.encrypt(plaintext, b'') self.assertEqual(plaintext, env_aead.decrypt(ciphertext, b''))
def test_encrypt_decrypt_missing_ad(self): key_template = aead.aead_key_templates.AES256_GCM keyset_handle = tink.new_keyset_handle(key_template) remote_aead = keyset_handle.primitive(aead.Aead) env_aead = aead.KmsEnvelopeAead(key_template, remote_aead) plaintext = b'helloworld' ciphertext = env_aead.encrypt(plaintext, b'envelope_ad') with self.assertRaises(core.TinkError): plaintext = env_aead.decrypt(ciphertext, b'')
def test_corrupted_dek(self): key_template = aead.aead_key_templates.AES256_GCM keyset_handle = tink.new_keyset_handle(key_template) remote_aead = keyset_handle.primitive(aead.Aead) env_aead = aead.KmsEnvelopeAead(key_template, remote_aead) plaintext = b'helloworld' ciphertext = bytearray(env_aead.encrypt(plaintext, b'some ad')) ciphertext[4] ^= 0x1 corrupted_ciphertext = bytes(ciphertext) with self.assertRaises(core.TinkError): plaintext = env_aead.decrypt(corrupted_ciphertext, b'some ad')
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 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 test_dek_extraction(self): key_template = aead.aead_key_templates.AES256_GCM keyset_handle = tink.new_keyset_handle(key_template) remote_aead = keyset_handle.primitive(aead.Aead) env_aead = aead.KmsEnvelopeAead(key_template, remote_aead) plaintext = b'helloworld' ciphertext = bytearray(env_aead.encrypt(plaintext, b'some ad')) # Decrypt DEK dek_len = struct.unpack('>I', ciphertext[0:aead.KmsEnvelopeAead.DEK_LEN_BYTES])[0] encrypted_dek_bytes = bytes(ciphertext[ aead.KmsEnvelopeAead.DEK_LEN_BYTES:aead.KmsEnvelopeAead.DEK_LEN_BYTES + dek_len]) dek_bytes = remote_aead.decrypt(encrypted_dek_bytes, b'') # Try to deserialize key key = aes_gcm_pb2.AesGcmKey.FromString(dek_bytes) self.assertLen(key.key_value, 32)