Enkripsi sisi klien dengan Tink dan Cloud KMS

Topik ini menjelaskan cara mengenkripsi data secara lokal dan menguploadnya ke Cloud Storage dengan Tink dan Cloud Key Management Service (Cloud KMS). Tink adalah library kriptografi open source yang ditulis oleh kriptografer dan engineer keamanan di Google.

Ringkasan

Enkripsi sisi klien adalah enkripsi apa pun yang dilakukan sebelum mengirim data ke cloud. Saat menggunakan enkripsi sisi klien, Anda bertanggung jawab untuk membuat dan mengelola kunci enkripsi serta mengenkripsi data sebelum mengirimkannya ke cloud.

Dalam topik ini, Anda akan menerapkan enkripsi menyeluruh sisi klien dengan Tink menggunakan kunci enkripsi di Cloud KMS.

Anda dapat menemukan versi cetak biru berbasis Terraform dari tutorial ini di repositori GitHub kms-solutions.

Sebelum memulai

  1. Buat kunci enkripsi Cloud KMS simetris untuk enkripsi. Catat URI kunci. Anda akan memerlukannya nanti.
  2. Instal Tink untuk digunakan dengan Cloud KMS.
  3. Buat bucket di Cloud Storage untuk mengupload data terenkripsi.

Peran yang diperlukan

Untuk memastikan akun layanan Anda memiliki izin yang diperlukan untuk menggunakan kunci Cloud KMS dengan Tink, minta administrator untuk memberikan peran IAM Pengenkripsi/Pendekripsi CryptoKey Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) ke akun layanan Anda di kunci Anda.

Untuk mengetahui informasi selengkapnya tentang cara memberikan peran, lihat Mengelola akses ke project, folder, dan organisasi.

Administrator Anda mungkin juga dapat memberikan izin yang diperlukan kepada akun layanan Anda melalui peran kustom atau peran yang telah ditetapkan.

Enkripsi menyeluruh dengan Tink

Dalam enkripsi menyeluruh, kunci Cloud KMS bertindak sebagai kunci enkripsi kunci (KEK). Artinya, kunci ini digunakan untuk mengenkripsi kunci enkripsi data (DEK) yang kemudian digunakan untuk mengenkripsi data sebenarnya.

Setelah membuat KEK di Cloud KMS, untuk mengenkripsi setiap pesan, Anda harus:

  1. Membuat kunci enkripsi data (DEK) secara lokal.
  2. Menggunakan DEK secara lokal untuk mengenkripsi pesan.
  3. Menggunakan Cloud KMS untuk mengenkripsi (menggabungkan) DEK dengan KEK.
  4. Menyimpan data terenkripsi dan DEK yang digabungkan.

Anda tidak perlu menerapkan proses enkripsi menyeluruh ini dari awal saat menggunakan Tink.

Untuk menggunakan Tink untuk enkripsi menyeluruh, Anda harus menyediakan Tink dengan URI kunci dan kredensial. URI kunci mengarah ke KEK Anda di Cloud KMS, dan kredensial memungkinkan Tink menggunakan KEK. Tink menghasilkan DEK, mengenkripsi data, menggabungkan DEK, lalu menampilkan satu ciphertext dengan data terenkripsi dan DEK yang digabungkan.

Tink mendukung enkripsi menyeluruh di Python, Java, C++, dan Go menggunakan primitif Enkripsi yang Diautentikasi dengan Data Terkait (AEAD).

Menghubungkan Tink dan Cloud KMS

Untuk mengenkripsi DEK yang dihasilkan oleh Tink dengan KEK Anda di Cloud KMS, Anda harus mendapatkan URI KEK Anda. Di Cloud KMS, URI KEK memiliki format berikut:

gcp-kms://projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/KEY_VERSION

Lihat Mendapatkan ID resource Cloud KMS untuk mengetahui detail cara mendapatkan jalur ke kunci Anda.

Menginisialisasi Tink dan mengenkripsi data

Tink menggunakan primitif—blok penyusun kriptografi yang mengelola detail algoritma dasarnya—sehingga Anda dapat melakukan tugas dengan aman. Setiap primitif menawarkan API yang menangani tugas tertentu. Di sini, kita menggunakan AEAD, jadi kita menggunakan primitif AEAD Tink.

Python

Python

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud KMS, lihat Library klien Cloud KMS.

Untuk melakukan autentikasi ke Cloud KMS, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

"""A command-line utility for performing file encryption using GCS.

It is inteded for use with small files, utilizes envelope encryption and
facilitates ciphertexts stored in GCS.
"""

from absl import app
from absl import flags
from absl import logging
from google.cloud import storage

import tink
from tink import aead
from tink.integration import gcpkms


FLAGS = flags.FLAGS

flags.DEFINE_enum('mode', None, ['encrypt', 'decrypt'],
                  'The operation to perform.')
flags.DEFINE_string('kek_uri', None,
                    'The Cloud KMS URI of the key encryption key.')
flags.DEFINE_string('gcp_credential_path', None,
                    'Path to the GCP credentials JSON file.')
flags.DEFINE_string('gcp_project_id', None,
                    'The ID of the GCP project hosting the GCS blobs.')
flags.DEFINE_string('local_path', None, 'Path to the local file.')
flags.DEFINE_string('gcs_blob_path', None, 'Path to the GCS blob.')


_GCS_PATH_PREFIX = 'gs://'


def main(argv):
  del argv  # Unused.

  # Initialise Tink
  aead.register()

  try:
    # Read the GCP credentials and setup client
    client = gcpkms.GcpKmsClient(FLAGS.kek_uri, FLAGS.gcp_credential_path)
  except tink.TinkError as e:
    logging.exception('Error creating GCP KMS client: %s', e)
    return 1

  # Create envelope AEAD primitive using AES256 GCM for encrypting the data
  try:
    remote_aead = client.get_aead(FLAGS.kek_uri)
    env_aead = aead.KmsEnvelopeAead(
        aead.aead_key_templates.AES256_GCM, remote_aead
    )
  except tink.TinkError as e:
    logging.exception('Error creating primitive: %s