Skip to content

Commit b018d04

Browse files
Russ Amosrsamborski
Russ Amos
authored andcommitted
KMS: Clean up base64 logic in the encrypt and decrypt functions. [(#1074)](#1074)
The use of base64 is essentially an implementation detail of the Cloud KMS REST API: it is required only so that arbitrary binary data can be included in a JSON string, which only allows Unicode characters. Therefore, the "encrypt" sample function should decode the base64-encoded ciphertext before writing the file. Similarly, "decrypt" should not assume that an input file is base64-encoded, but should perform the base64-encoding itself before sending the encrypted data to KMS. This aligns with how the "gcloud kms encrypt" and "gcloud kms decrypt" commands behave. See https://stackoverflow.com/q/45699472 for an example of user confusion caused by the mismatch.
1 parent 107bf55 commit b018d04

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

kms/snippets/snippets.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,18 @@ def encrypt(project_id, location, keyring, cryptokey, plaintext_file_name,
7777
# Read text from the input file.
7878
with io.open(plaintext_file_name, 'rb') as plaintext_file:
7979
plaintext = plaintext_file.read()
80-
encoded_text = base64.b64encode(plaintext)
8180

8281
# Use the KMS API to encrypt the text.
8382
cryptokeys = kms_client.projects().locations().keyRings().cryptoKeys()
8483
request = cryptokeys.encrypt(
85-
name=name, body={'plaintext': encoded_text.decode('utf-8')})
84+
name=name,
85+
body={'plaintext': base64.b64encode(plaintext).decode('ascii')})
8686
response = request.execute()
87+
ciphertext = base64.b64decode(response['ciphertext'].encode('ascii'))
8788

8889
# Write the encrypted text to a file.
8990
with io.open(encrypted_file_name, 'wb') as encrypted_file:
90-
encrypted_file.write(response['ciphertext'].encode('utf-8'))
91+
encrypted_file.write(ciphertext)
9192

9293
print('Saved encrypted text to {}.'.format(encrypted_file_name))
9394
# [END kms_encrypt]
@@ -109,19 +110,19 @@ def decrypt(project_id, location, keyring, cryptokey, encrypted_file_name,
109110

110111
# Read cipher text from the input file.
111112
with io.open(encrypted_file_name, 'rb') as encrypted_file:
112-
cipher_text = encrypted_file.read()
113+
ciphertext = encrypted_file.read()
113114

114115
# Use the KMS API to decrypt the text.
115116
cryptokeys = kms_client.projects().locations().keyRings().cryptoKeys()
116117
request = cryptokeys.decrypt(
117-
name=name, body={'ciphertext': cipher_text.decode('utf-8')})
118+
name=name,
119+
body={'ciphertext': base64.b64encode(ciphertext).decode('ascii')})
118120
response = request.execute()
121+
plaintext = base64.b64decode(response['plaintext'].encode('ascii'))
119122

120123
# Write the plain text to a file.
121124
with io.open(decrypted_file_name, 'wb') as decrypted_file:
122-
plaintext_encoded = response['plaintext']
123-
plaintext_decoded = base64.b64decode(plaintext_encoded)
124-
decrypted_file.write(plaintext_decoded)
125+
decrypted_file.write(plaintext)
125126

126127
print('Saved decrypted text to {}.'.format(decrypted_file_name))
127128
# [END kms_decrypt]

0 commit comments

Comments
 (0)