Enkripsi level kolom dengan Cloud KMS

Anda dapat menggunakan Cloud Key Management Service (Cloud KMS) untuk mengenkripsi kunci yang kemudian akan mengenkripsi nilai dalam tabel BigQuery. Anda dapat menggunakan fungsi enkripsi AEAD dengan keyset Cloud KMS atau keyset gabungan untuk memberikan lapisan perlindungan kedua pada level kolom.

Pengantar

Untuk memberikan lapisan perlindungan tambahan, Cloud KMS akan mengenkripsi kunci enkripsi data (DEK) Anda dengan kunci enkripsi kunci kedua (KEK). Pada BigQuery, mereferensikan keyset terenkripsi, bukan keyset teks biasa, akan membantu mengurangi risiko eksposur kunci. KEK adalah keyset enkripsi simetris yang disimpan dengan aman di Cloud KMS dan dikelola menggunakan peran serta izin Identity and Access Management (IAM).

BigQuery mendukung fungsi enkripsi deterministik dan non-deterministik. Dengan enkripsi deterministik, jika bagian data yang disimpan dan data tambahan yang diautentikasi (opsional) identik, maka ciphertext akan identik. Hal ini memungkinkan dukungan agregasi dan penggabungan berdasarkan kolom yang dienkripsi. Dengan enkripsi non-deterministik, ciphertext yang disimpan akan bersifat unik terlepas dari data yang dienkripsi, yang mencegah pengelompokan, agregasi, dan penggabungan.

Pada waktu eksekusi kueri, Anda memberikan jalur resource Cloud KMS KEK dan ciphertext dari DEK gabungan. BigQuery akan memanggil Cloud KMS untuk membuka DEK, lalu menggunakan kunci tersebut untuk mendekripsi data dalam kueri Anda. Versi DEK yang tidak digabungkan hanya disimpan dalam memori selama durasi kueri, lalu dihancurkan.

Jika menggunakan Cloud KMS di region tempat Cloud External Key Manager didukung, Anda dapat menggunakan kunci berbasis Cloud EKM di Cloud KMS.

Kasus penggunaan

Kasus penggunaan untuk enkripsi dengan kunci Cloud KMS mencakup hal berikut:

  • Data yang dienkripsi secara eksternal yang perlu disimpan di BigQuery tanpa menyimpan keyset dalam teks biasa. Data Anda kemudian dapat diekspor dari tabel atau didekripsi dengan kueri SQL.
  • "Kontrol akses ganda" atas data terenkripsi di BigQuery. Pengguna harus diberi izin ke tabel dan kunci enkripsi untuk membaca data dalam cleartext.
Matriks Izin Pengguna
Izin di Tabel Tidak Ada Izin di Tabel
Izin di Kunci Membaca dan mendekripsi data terenkripsi. Tidak ada akses.
Tidak Ada Izin pada Kunci Membaca data terenkripsi. Tidak ada akses.

Jika pengguna memiliki izin untuk mengakses kunci KMS dan memiliki akses ke keyset gabungan, fungsi SQL dapat membuka keyset dan mendekripsi ciphertext. Pengguna juga dapat menggunakan REST API atau CLI Cloud KMS untuk membuka keyset.
Contoh kueri berikut menggunakan fungsi KMS SQL untuk mendekripsi ciphertext non-deterministik:

SELECT
  AEAD.DECRYPT_STRING(
    KEYS.KEYSET_CHAIN(@kms_resource_name, @first_level_keyset),
    ciphertext,
    additional_authenticated_data)
FROM
  ciphertext_table
WHERE
  ...

Contoh kasus penggunaan

Asumsikan implementasi saat kode pos dianggap sebagai informasi sensitif. Data kode pos dapat disisipkan ke dalam tabel BigQuery menggunakan fungsi enkripsi AEAD, sehingga mengenkripsi kolom Zipcode. Dalam contoh ini, kami menggunakan fungsi AEAD.ENCRYPT dengan fungsi pengelolaan keyset gabungan. Fungsi KEYS.KEYSET_CHAIN akan mengenkripsi kunci enkripsi digital dengan KEK, dan fungsi AEAD.ENCRYPT akan meneruskan informasi ke KMS.

Rantai keyset untuk enkripsi dan dekripsi akan memastikan bahwa kunci enkripsi data (DEK) dienkripsi atau dibungkus dengan KEK dan diteruskan dengan KEK tersebut. DEK gabungan didekripsi atau dibuka dalam fungsi SQL, lalu digunakan untuk mengenkripsi atau mendekripsi data.

Fungsi non-deterministik AEAD dapat mendekripsi data saat diakses menggunakan fungsi dalam kueri yang sedang dijalankan di tabel.

gambar

Fungsi deterministik AEAD dapat mendekripsi data saat diakses dengan menggunakan fungsi dalam kueri yang dijalankan di tabel dan mendukung agregasi serta penggabungan menggunakan data terenkripsi.

gambar

Sintaksis fungsi non-deterministik

Sintaksis yang didukung untuk menggunakan fungsi non-deterministik mencakup hal berikut:

AEAD.ENCRYPT(
  KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
  plaintext,
  additional_authenticated_data)
AEAD.DECRYPT_STRING(
  KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
  ciphertext,
  additional_authenticated_data)
AEAD.DECRYPT_BYTES(
  KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
  ciphertext,
  additional_authenticated_data)

Lihat sintaksis fungsi AEAD.DECRYPT_BYTES, AEAD.ENCRYPT, AEAD.DECRYPT_STRING, dan KEYS.KEYSET_CHAIN.

Sintaksis fungsi deterministik

Sintaksis yang didukung untuk menggunakan fungsi deterministik mencakup hal berikut:

DETERMINISTIC_ENCRYPT(
  KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
  plaintext,
  additional_data)
DETERMINISTIC_DECRYPT_STRING(
  KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
  ciphertext,
  additional_data)
DETERMINISTIC_DECRYPT_BYTES(
  KEYS.KEYSET_CHAIN(kms_resource_name, first_level_keyset),
  ciphertext,
  additional_data)

Lihat sintaksis fungsi DETERMINISTIC_DECRYPT_BYTES, DETERMINISTIC_ENCRYPT, DETERMINISTIC_DECRYPT_STRING, dan KEYS.KEYSET_CHAIN.

Peran dan izin

Untuk daftar peran Cloud KMS, baca izin dan peran Cloud KMS.

Batasan

Enkripsi dengan Cloud KMS memiliki batasan dan pembatasan berikut:

  • Kunci Cloud KMS dibatasi ke region atau multi-region yang sama dengan kueri. Penggunaan kunci Cloud KMS global tidak diizinkan untuk alasan keandalan.

  • Anda tidak dapat memutar keyset gabungan menggunakan fungsi KEYS.ROTATE_KEYSET.

  • Parameter konstan dalam kueri BigQuery terlihat oleh pengguna dalam paket kueri diagnostik. Faktor ini dapat memengaruhi parameter kms_resource_name dan first_level_keyset fungsi KEYSET_CHAIN. Kunci tidak pernah diekspos dalam teks biasa, dan izin ke kunci Cloud KMS diperlukan untuk mendekripsi keyset gabungan. Pendekatan ini memastikan bahwa kunci tidak diekspos melalui paket kueri diagnostik kecuali pengguna memiliki izin untuk mendekripsi keyset.

  • Enkripsi level kolom memiliki batasan berikut saat digunakan dengan klasifikasi keamanan berbasis jenis:

    • Keamanan level kolom: Pengguna hanya dapat mendekripsi atau mengenkripsi data pada kolom diizinkan untuk diakses.

    • Keamanan level baris: Pengguna hanya dapat mendekripsi data pada baris yang diizinkan untuk diakses.

  • Fungsi SQL level kolom tidak memiliki dampak signifikan terhadap performa jika dibandingkan dengan performa fungsi enkripsi mentah tempat data kunci dikirim dalam teks biasa.

Sebelum memulai

Untuk bekerja dengan kunci, keyset, tabel terenkripsi, fungsi deterministik, dan non-deterministik Cloud KMS, Anda harus melakukan hal berikut jika belum melakukannya:

  1. Buat project Google Cloud.

  2. Buat set data BigQuery.

  3. Buat key ring Cloud KMS.

  4. Buat kunci Cloud KMS untuk kolom terenkripsi dengan level perlindungan software atau Hardware Security Module (HSM).

  5. Berikan izin kepada pengguna untuk menggunakan kunci, enkripsi, dan dekripsi Cloud KMS.

Perhatikan konsep berikut, seperti yang dirujuk di bagian berikutnya:

  • PROJECT_ID: Nama project Google Cloud.

  • DATASET_NAME: Nama set data BigQuery.

  • LOCATION_ID: Lokasi set data BigQuery.

  • TABLE_NAME: Nama tabel BigQuery.

  • KEY_RING_ID: Nama key ring Cloud KMS.

  • KEY_ID: Nama kunci Cloud KMS.

  • KMS_KEY: Kunci Cloud KMS (KEK) dalam format ini:

    'gcp-kms://projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEY_RING_ID/cryptoKeys/KEY_ID'

    Berikut adalah contoh kunci Cloud KMS:

    'gcp-kms://projects/myProject/locations/us/keyRings/myKeyRing/cryptoKeys/myKeyName'
    
  • KMS_KEY_SHORT: Serupa dengan KMS_KEY, tetapi dalam format ini:

    projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEY_RING_ID/cryptoKeys/KEY_ID
  • KEYSET_DECODED: Keyset yang didekode sebagai urutan BYTES. Outputnya terlihat mirip dengan keyset gabungan yang didekode.

    Meskipun fungsi keyset menampilkan keyset sebagai byte, namun output pengguna ditampilkan sebagai string yang dienkode. Untuk mengonversi keyset yang dienkode menjadi keyset yang didekode, baca Mendekode keyset Cloud KMS

  • KEYSET_ENCODED: Keyset yang dienkode sebagai STRING. Outputnya terlihat mirip dengan keyset gabungan yang dienkode.

    Untuk mengonversi keyset yang dienkode menjadi keyset yang didekode, baca Mendekode keyset Cloud KMS

  • WRAPPED_KEYSET_DECODED: Keyset gabungan yang didekode sebagai urutan BYTES. Berikut adalah contoh tampilan output-nya:

    b'\x0a$\x00\xa6\xee\x12Y\x8d|l"\xf7\xfa\xc6\xeafM\xdeefy\xe9\x7f\xf2z\xb3M\
    xf6"\xd0\xe0Le\xa8\x8e\x0fR\xed\x12\xb7\x01\x00\xf0\xa80\xbd\xc1\x07Z\\
    \xd0L<\x80A0\x9ae\xfd(9\x1e\xfa\xc8\x93\xc7\xe8\...'
    

    Meskipun fungsi keyset gabungan menampilkan keyset gabungan sebagai byte, namun output pengguna ditampilkan sebagai string yang dienkode. Untuk mengonversi keyset gabungan yang dienkode menjadi keyset gabungan yang didekode, baca Mendekode keyset Cloud KMS

  • WRAPPED_KEYSET_ENCODED: Keyset gabungan yang dienkode sebagai STRING. Berikut adalah contoh tampilan output-nya:

    'CiQApu4SWTozQ7lNwITxpEvGlo5sT2rv1tyuSv3UAMtoTq/lhDwStwEA8KgwvX7CpVVzhWWMkRw
    WZNr3pf8uBIlzHeunCy8ZsQ6CofQYFpiBRBB6k/QqATbiFV+3opnDk/6dBL/S8OO1WoDC+DdD9
    uzEFwqt5D20lTXCkGWFv1...'
    

    Untuk mengonversi keyset gabungan yang dienkode menjadi keyset gabungan yang didekode, baca Mendekode keyset Cloud KMS

Pengelolaan kunci

Bagian berikut berisi tugas umum yang dapat Anda lakukan dengan kunci Cloud KMS.

Membuat keyset

Anda dapat membuat keyset gabungan atau keyset mentah. Untuk melakukannya, selesaikan langkah-langkah di bagian berikut ini.

Membuat keyset mentah

Jalankan kueri berikut untuk membuat keyset dengan kunci jenis DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

SELECT KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') AS raw_keyset

Membuat keyset gabungan

Jalankan kueri berikut untuk membuat keyset gabungan Cloud KMS dengan kunci jenis DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

SELECT KEYS.NEW_WRAPPED_KEYSET(
  KMS_KEY,
  'DETERMINISTIC_AEAD_AES_SIV_CMAC_256')

Mendekode keyset

Meskipun fungsi SQL yang menampilkan keyset menghasilkan keyset dalam format BYTES, hasil yang ditampilkan pengguna akan dienkode dan ditampilkan dalam format STRING. Jika Anda ingin mengonversi string yang dienkode ini menjadi urutan byte yang didekode dan dapat Anda gunakan sebagai fungsi enkripsi kunci literal, gunakan kueri berikut.

Mendekode keyset gabungan

Jalankan kueri berikut untuk mendekode keyset gabungan Cloud KMS.

SELECT FORMAT('%T', FROM_BASE64(WRAPPED_KEYSET_ENCODED'))

Mendekode keyset mentah

Jalankan kueri berikut untuk mendekode keyset mentah.

SELECT FORMAT('%T', FROM_BASE64(KEYSET_ENCODED'))

Menggabungkan ulang keyset gabungan

Jalankan kueri berikut untuk menggabungkan ulang keyset gabungan Cloud KMS dengan kunci Cloud KMS baru. KMS_KEY_CURRENT merepresentasikan KMS_KEY baru yang digunakan untuk mengenkripsi keyset. KMS_KEY_NEW merepresentasikan KMS_KEY baru yang digunakan untuk mengenkripsi keyset.

SELECT KEYS.REWRAP_KEYSET(
  KMS_KEY_CURRENT,
  KMS_KEY_NEW,
  WRAPPED_KEYSET_DECODED)

Merotasi keyset gabungan

Jalankan kueri berikut untuk merotasi keyset gabungan Cloud KMS dengan kunci jenis DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

SELECT KEYS.ROTATE_WRAPPED_KEYSET(
  KMS_KEY,
  WRAPPED_KEYSET_DECODED,
  'DETERMINISTIC_AEAD_AES_SIV_CMAC_256')

Membuat keyset mentah dari keyset gabungan

Beberapa fungsi enkripsi memerlukan keyset mentah. Untuk mendekripsi keyset gabungan Cloud KMS guna menghasilkan keyset mentah, selesaikan langkah-langkah berikut.

  1. Buat keyset gabungan.

  2. Pada alat command line bq, masukkan perintah berikut untuk menyimpan keyset gabungan dalam file bernama keyset_to_unwrap, dekripsi keyset gabungan, dan hasilkan output dalam format KEYSET_DECODED:

    echo WRAPPED_KEYSET_ENCODED | base64 -d > /tmp/decoded_wrapped_key
    gcloud kms decrypt \
    --ciphertext-file=/tmp/decoded_wrapped_key \
    --key=KMS_KEY_SHORT \
    --plaintext-file=/tmp/keyset_to_unwrap.dec \
    --project=PROJECT_ID
    od -An --format=o1 /tmp/keyset_to_unwrap.dec | tr ' ' '\'

Membuat keyset gabungan dari keyset mentah

Beberapa fungsi enkripsi memerlukan keyset gabungan Cloud KMS. Untuk mengenkripsi keyset mentah guna menghasilkan keyset gabungan, selesaikan langkah-langkah berikut.

  1. Buat keyset mentah.

  2. Pada alat command line bq, masukkan perintah berikut untuk menyimpan keyset mentah dalam file bernama keyset_to_wrap, enkripsi keyset mentah tersebut, dan hasilkan output dalam format WRAPPED_KEYSET_DECODED:

    echo KEYSET_ENCODED | base64 -d > /tmp/decoded_key
    gcloud kms encrypt \
    --plaintext-file=/tmp/decoded_key \
    --key=KMS_KEY_SHORT \
    --ciphertext-file=/tmp/keyset_to_wrap.dec \
    --project=PROJECT_ID
    od -An --format=o1 /tmp/keyset_to_wrap.dec | tr ' ' '\'

Membuat kunci gabungan untuk fungsi DLP

Untuk fungsi DLP, Anda memerlukan kunci kriptografis, lalu menggunakan kunci tersebut untuk mendapatkan kunci gabungan.

  1. Untuk membuat kunci kriptografis baru, di command line, jalankan perintah berikut. Ukuran kunci dapat berupa 16, 24, atau 32 byte. Contoh berikut menggunakan kunci 16 byte:

    openssl rand 16 > rand.key.16.bin
    
  2. Gabungkan kunci 16 byte yang dihasilkan dengan kunci KMS. Lihat contoh berikut:

    KEYRING=projects/myproject/locations/us/keyRings/kms-test
    KEY=projects/myproject/locations/us/keyRings/kms-test/cryptoKeys/test-Kek
    PROJECT="myproject"
    
    gcloud kms encrypt --project $PROJECT --location us --keyring $KEYRING --key $KEY --plaintext-file ./rand.key.16.bin --ciphertext-file ./rand.key.16.wrapped
    
  3. Sekarang Anda bisa mendapatkan literal BYTES dari kunci gabungan atau format base64 kunci gabungan.

    • Literal byte

      username:~/tmp$ od -b ./rand.key.16.wrapped | cut -d ' ' -f 2- | head -n -1 | sed  -e 's/^/ /' | tr ' ' '\'
      

      Outputnya akan terlihat seperti berikut:

      \012\044\000\325\155\264\153\246\071\172\130\372\305\103\047\342\356\061\077\014\030\126\147\041\126\150\012\036\020\202\215\044\267\310\331\014\116\233\022\071\000\363\344\230\067\274\007\340\273\016\212\151\226\064\200\377\303\207\103\147\052\267\035\350\004\147\365\251\271\133\062\251\246\152\177\017\005\270\044\141\211\116\337\043\035\263\122\340\110\333\266\220\377\247\204\215\233
      
    • Format Base64

      username:~/tmp$ base64 ./rand.key.16.wrapped
      

      Outputnya akan terlihat seperti berikut:

      CiQA1W20a6Y5elj6xUMn4u4xPwwYVmchVmgKHhCCjSS3yNkMTpsSOQDz5Jg3vAfguw6KaZY0gP/Dh0NnKrcd6ARn9am5WzKppmp/DwW4JGGJTt8jHbNS4EjbtpD/p4SNmw==
      

Mendapatkan jumlah kunci dalam keyset

Jalankan kueri berikut untuk mendapatkan jumlah kunci dalam keyset mentah.

  1. Jika Anda menggunakan keyset gabungan, buat keyset mentah terlebih dahulu.

  2. Jalankan kueri ini dengan keyset mentah:

    SELECT KEYS.KEYSET_LENGTH(KEYSET_DECODED) as key_count;

Mendapatkan representasi JSON keyset

Jalankan kueri berikut untuk melihat representasi JSON keyset mentah.

  1. Jika Anda menggunakan keyset gabungan, buat keyset mentah terlebih dahulu.

  2. Jalankan kueri ini dengan keyset mentah:

    SELECT KEYS.KEYSET_TO_JSON(KEYSET_DECODED);

Enkripsi dan dekripsi

Anda dapat menggunakan keyset mentah atau keyset gabungan untuk mengenkripsi kolom dalam tabel. Anda juga dapat memilih untuk menggunakan enkripsi deterministik atau non-deterministik di kolom. Contoh di bagian ini menggunakan keyset gabungan, tetapi Anda dapat mengganti keyset yang digabungkan dengan keyset mentah.

Enkripsi kolom secara deterministik dengan keyset gabungan

Jalankan kueri berikut untuk membuat tabel dan menyimpan keyset gabungan Cloud KMS dengan enkripsi deterministik di kolom yang disebut encrypted_content.

  1. Buat keyset gabungan.

  2. Enkripsi kolom dengan keyset gabungan.

    CREATE OR REPLACE TABLE DATASET_NAME.TABLE_NAME AS
      SELECT DETERMINISTIC_ENCRYPT(
        KEYS.KEYSET_CHAIN(KMS_KEY, WRAPPED_KEYSET_DECODED),
        'plaintext',
        '') AS encrypted_content

Mendekripsi kolom secara deterministik dengan keyset gabungan

Jalankan kueri berikut untuk mendekripsi kolom secara deterministik yang berisi konten terenkripsi, menggunakan keyset gabungan Cloud KMS. Kueri ini mengasumsikan bahwa Anda mereferensikan tabel dengan kolom bernama encrypted_content.

SELECT DETERMINISTIC_DECRYPT_STRING(
  KEYS.KEYSET_CHAIN(KMS_KEY, WRAPPED_KEYSET_DECODED),
  encrypted_content,
  '')
FROM DATASET_NAME.TABLE_NAME

Mengenkripsi kolom secara non-deterministik dengan keyset gabungan

Lihat Mengenkripsi kolom secara deterministik dengan keyset gabungan, tetapi mengganti DETERMINISTIC_ENCRYPT dengan AEAD.ENCRYPT. Pastikan keyset Anda berjenis AEAD_AES_GCM_256.

Mendekripsi kolom secara non-deterministik dengan keyset gabungan

Lihat Mendekripsi kolom secara deterministik dengan keyset gabungan, tetapi mengganti DETERMINISTIC_DECRYPT_STRING dengan AEAD.DECRYPT_STRING. Pastikan keyset Anda berjenis AEAD_AES_GCM_256.

Langkah berikutnya

  • Pelajari Cloud KMS lebih lanjut. Topik ini mencakup informasi konseptual tentang enkripsi level kolom untuk Google Cloud.
  • Pelajari enkripsi AEAD untuk BigQuery lebih lanjut. Topik ini mencakup informasi konseptual tentang enkripsi level kolom khusus untuk BigQuery.
  • Pelajari fungsi enkripsi AEAD untuk BigQuery lebih lanjut. Topik ini berisi semua fungsi SQL yang dapat Anda gunakan untuk enkripsi level kolom di BigQuery.