@@ -38,14 +38,45 @@ def encrypt_symmetric(project_id, location_id, key_ring_id, key_id, plaintext):
3838 # Convert the plaintext to bytes.
3939 plaintext_bytes = plaintext .encode ('utf-8' )
4040
41+ # Optional, but recommended: compute plaintext's CRC32C.
42+ # See crc32c() function defined below.
43+ plaintext_crc32c = crc32c (plaintext_bytes )
44+
4145 # Create the client.
4246 client = kms .KeyManagementServiceClient ()
4347
4448 # Build the key name.
4549 key_name = client .crypto_key_path (project_id , location_id , key_ring_id , key_id )
4650
4751 # Call the API.
48- encrypt_response = client .encrypt (request = {'name' : key_name , 'plaintext' : plaintext_bytes })
52+ encrypt_response = client .encrypt (
53+ request = {'name' : key_name , 'plaintext' : plaintext_bytes , 'plaintext_crc32c' : plaintext_crc32c })
54+
55+ # Optional, but recommended: perform integrity verification on encrypt_response.
56+ # For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
57+ # https://cloud.google.com/kms/docs/data-integrity-guidelines
58+ if not encrypt_response .verified_plaintext_crc32c :
59+ raise Exception ('The request sent to the server was corrupted in-transit.' )
60+ if not encrypt_response .ciphertext_crc32c == crc32c (encrypt_response .ciphertext ):
61+ raise Exception ('The response received from the server was corrupted in-transit.' )
62+ # End integrity verification
63+
4964 print ('Ciphertext: {}' .format (base64 .b64encode (encrypt_response .ciphertext )))
5065 return encrypt_response
66+
67+
68+ def crc32c (data ):
69+ """
70+ Calculates the CRC32C checksum of the provided data.
71+
72+ Args:
73+ data: the bytes over which the checksum should be calculated.
74+
75+ Returns:
76+ An int representing the CRC32C checksum of the provided bytes.
77+ """
78+ import crcmod
79+ import six
80+ crc32c_fun = crcmod .predefined .mkPredefinedCrcFun ('crc-32c' )
81+ return crc32c_fun (six .ensure_binary (data ))
5182# [END kms_encrypt_symmetric]
0 commit comments