README.md
1# Python Google Cloud Storage (GCS) client-side encryption example
2
3This example shows how to encrypt/decrypt GCS blobs with Tink using
4[Envelope Encryption](https://cloud.google.com/kms/docs/envelope-encryption).
5
6It shows how you can use Tink to encrypt data with a newly generated *data
7encryption key* (DEK) which is wrapped with a KMS key. The data will be
8encrypted with AES256 GCM using the DEK and the DEK will be encrypted with the
9KMS key and stored alongside the ciphertext in GCS.
10
11The CLI takes the following required arguments:
12
13* `--mode`: Either `encrypt` or `decrypt` to indicate if you want to encrypt
14 or decrypt.
15* `--kek_uri`: The URI for the Cloud KMS key to be used for envelope encryption.
16* `--gcp_credential_path`: Name of the file with the Google Cloud Platform (GCP)
17 credentials (in JSON format) that can access the Cloud KMS key and the GCS
18 input/output blobs.
19* `--gcp_project_id`: The ID of the GCP project hosting the GCS blobs that you
20 want to encrypt or decrypt.
21* `--local_path`:
22 * When `--mode encrypt`, read the plaintext from this local file.
23 * When `--mode decrypt`, write the decryption result to this local file.
24* `--gcs_blob_path`:
25 * Format: `gs://my-bucket-name/my-object-name`
26 * When `--mode encrypt`, write the encryption result to this blob in GCS.
27 The encryption result is bound to the location of this blob. That is, if
28 you rename or move it to a different bucket, decryption will fail.
29 * When `--mode decrypt`, read the ciphertext from this blob in GCS.
30
31## Build and run
32
33### Prequisite
34
35This envelope encryption example uses a Cloud KMS key as a key-encryption key
36(KEK). In order to run it, you need to:
37
38* Create a symmetric key on Cloud KMS. Copy the key URI which is in this
39 format:
40 `projects/<my-project>/locations/global/keyRings/<my-key-ring>/cryptoKeys/<my-key>`
41
42* Create a bucket on GCS.
43
44* Create a service account that is allowed to encrypt and decrypt with the
45 Cloud KMS key, and read/write to the GCS bucket. Then download the JSON
46 credentials file.
47
48### Bazel
49
50Build the examples:
51
52```shell
53$ git clone https://github.com/google/tink
54$ cd tink/python/examples
55$ bazel build ...
56```
57
58You can then encrypt a file and upload the result to GCS:
59
60```shell
61$ echo "some data" > testdata.txt
62$ ./bazel-bin/gcs/gcs_envelope_aead \
63 --mode encrypt \
64 --kek_uri gcp-kms://my-cloud-kms-key-uri \
65 --gcp_credential_path my-service-account.json \
66 --gcp_project_id my-gcp-project-id \
67 --local_path testdata.txt \
68 --gcs_blob_path gs://my-bucket-name/my-blob-name
69```
70
71Or download a file from GCS and decrypt it:
72
73```shell
74$ ./bazel-bin/gcs/gcs_envelope_aead
75 --mode decrypt \
76 --kek_uri gcp-kms://my-key-uri \
77 --gcp_credential_path my-service-account.json \
78 --gcp_project_id my-gcp-project-id \
79 --gcs_blob_path gs://my-bucket-name/my-blob-name \
80 --local_path testdata.txt.decrypted
81```
82