Crittografia a livello di colonna con Cloud KMS

Puoi utilizzare Cloud Key Management Service (Cloud KMS) per criptare le chiavi che a loro volta criptano i valori all'interno delle tabelle BigQuery. Puoi utilizzare le funzioni di crittografia AEAD con i keyset o i keyset sottoposti a wrapping di Cloud KMS per fornire un secondo livello di protezione a livello di colonna.

Introduzione

Per fornire un ulteriore livello di protezione, Cloud KMS cripta la chiave di crittografia dei dati (DEK) con una seconda chiave di crittografia della chiave (KEK). In BigQuery, fare riferimento a un keyset criptato anziché a un keyset in testo non criptato contribuisce a ridurre il rischio di esposizione delle chiavi. La KEK è un insieme di chiavi di crittografia simmetriche archiviato in modo sicuro in Cloud KMS e gestito utilizzando ruoli e autorizzazioni Identity and Access Management (IAM).

BigQuery supporta funzioni di crittografia deterministiche e non deterministiche. Con la crittografia deterministica, se sia i dati archiviati sia i dati autenticati aggiuntivi (facoltativi) sono identici, anche il testo criptato è identico. Ciò consente il supporto di aggregazioni e join in base alla colonna criptata. Con la crittografia non deterministica, il testo cifrato archiviato è univoco indipendentemente dai dati criptati, il che impedisce il clustering, l'aggregazione e i join.

Al momento dell'esecuzione della query, fornisci il percorso della risorsa Cloud KMS della KEK e il testo cifrato della DEK sottoposta a wrapping. BigQuery chiama Cloud KMS per decomprimere la chiave DEK, quindi utilizza questa chiave per decriptare i dati nella query. La versione non sottoposta a wrapping della DEK viene archiviata in memoria solo per la durata della query e poi viene eliminata.

Se utilizzi Cloud KMS in una regione in cui è supportato Cloud External Key Manager, puoi utilizzare le chiavi basate su Cloud EKM in Cloud KMS.

Casi d'uso

I casi d'uso per la crittografia con le chiavi Cloud KMS includono:

  • Dati criptati esternamente che devono essere archiviati in BigQuery senza archiviare il keyset in testo non criptato. I dati possono quindi essere esportati dalla tabella o decriptati con una query SQL.
  • "Doppio controllo dell'accesso" ai dati criptati in BigQuery. Un utente deve disporre dell'autorizzazione sia per la tabella sia per la chiave di crittografia per leggere i dati in testo non crittografato.
Matrice delle autorizzazioni utente
Autorizzazione sulla tabella Nessuna autorizzazione sulla tabella
Autorizzazioni sulla chiave Leggere e decriptare i dati criptati. Nessun accesso.
Nessuna autorizzazione sulla chiave Leggere i dati criptati. Nessun accesso.

Se un utente ha l'autorizzazione per accedere alla chiave KMS e ha accesso al keyset sottoposto a wrapping, le funzioni SQL possono decomprimere il keyset e decriptare il testo criptato. Gli utenti possono anche utilizzare l'API REST o la CLI di Cloud KMS per decriptare il keyset.
Il seguente esempio di query utilizza le funzioni SQL di KMS per decriptare il testo cifrato non deterministico:

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

Esempio di caso d'uso

Supponiamo un'implementazione in cui i codici postali sono considerati informazioni sensibili. I dati del codice postale possono essere inseriti nella tabella BigQuery utilizzando la funzione di crittografia AEAD, in modo da criptare la colonna Zipcode. In questo esempio, utilizziamo la funzione AEAD.ENCRYPT con la funzione di gestione del keyset con wrapping. La funzione KEYS.KEYSET_CHAIN decripta la chiave di crittografia digitale con la KEK e la funzione AEAD.ENCRYPT passa le informazioni a KMS.

La catena di keyset per la crittografia e la decrittografia garantisce che la chiave di crittografia dei dati (DEK) sia criptata o sottoposta a wrapping con una KEK e trasmessa con quella KEK. La DEK sottoposta a wrapping viene decriptata o di cui viene annullato il wrapping all'interno della funzione SQL e poi utilizzata per criptare o decriptare i dati.

La funzione non deterministica AEAD può decriptare i dati quando vi si accede utilizzando la funzione nella query eseguita sulla tabella.

immagine

La funzione deterministica AEAD può decriptare i dati quando vengono accessibili utilizzando la funzione nella query eseguita sulla tabella e supporta l'aggregazione e i join utilizzando i dati criptati.

immagine

Sintassi della funzione non deterministica

La sintassi supportata per l'utilizzo di funzioni non deterministiche include quanto segue:

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)

Consulta la sintassi delle funzioni AEAD.DECRYPT_BYTES, AEAD.ENCRYPT, AEAD.DECRYPT_STRING e KEYS.KEYSET_CHAIN.

Sintassi della funzione deterministica

La sintassi supportata per l'utilizzo di funzioni deterministiche include quanto segue:

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)

Consulta la sintassi delle funzioni DETERMINISTIC_DECRYPT_BYTES, DETERMINISTIC_ENCRYPT, DETERMINISTIC_DECRYPT_STRING e KEYS.KEYSET_CHAIN.

Ruoli e autorizzazioni

Per un elenco dei ruoli per Cloud KMS, consulta Ruoli e autorizzazioni di Cloud KMS.

Limitazioni

La crittografia con Cloud KMS presenta le seguenti limitazioni e restrizioni:

  • Le chiavi Cloud KMS sono limitate alla stessa regione o multiregione della query. L'utilizzo delle chiavi Cloud KMS globali non è consentito per motivi di affidabilità.

  • Non è possibile ruotare un insieme di chiavi sottoposto a wrapping utilizzando la funzione KEYS.ROTATE_KEYSET.

  • I parametri costanti in una query BigQuery sono visibili agli utenti nel piano di query diagnostico. Questo fattore può influire sui parametri kms_resource_name e first_level_keyset della funzione KEYSET_CHAIN. Le chiavi non vengono mai esposte in testo non crittografato ed è necessaria l'autorizzazione per la chiave Cloud KMS per decriptare il keyset sottoposto a wrapping. Questo approccio garantisce che le chiavi non vengano esposte tramite il piano di query diagnostico, a meno che l'utente non disponga dell'autorizzazione per decriptare il keyset.

  • La crittografia a livello di colonna presenta le seguenti limitazioni se utilizzata con classificazioni di sicurezza basate sul tipo:

    • Sicurezza a livello di colonna: gli utenti possono decriptare o criptare i dati solo nelle colonne a cui è consentito l'accesso.

    • Sicurezza a livello di riga: gli utenti possono decriptare i dati solo nelle righe a cui è consentito l'accesso.

  • Le funzioni SQL a livello di colonna non hanno un impatto significativo sulle prestazioni rispetto a quelle delle funzioni di crittografia non elaborate in cui i dati della chiave vengono inviati in testo non crittografato.

Prima di iniziare

Per lavorare con chiavi, keyset, tabelle criptate, funzioni deterministiche e non deterministiche di Cloud KMS, devi eseguire le seguenti operazioni, se non le hai già eseguite:

  1. Crea un Google Cloud progetto.

  2. Crea un set di dati BigQuery.

  3. Crea un keyring Cloud KMS.

  4. Crea una chiave Cloud KMS per una colonna criptata con il livello di protezione software o modulo di sicurezza hardware (HSM).

  5. Concedi le autorizzazioni utente per lavorare con le chiavi, la crittografia e la decrittografia di Cloud KMS.

Tieni presente i seguenti concetti, a cui si fa riferimento nelle sezioni successive:

  • PROJECT_ID: il nome del progetto Google Cloud.

  • DATASET_NAME: il nome del set di dati BigQuery.

  • LOCATION_ID: la posizione del set di dati BigQuery.

  • TABLE_NAME: il nome della tabella BigQuery.

  • KEY_RING_ID: il nome delle chiavi automatizzate Cloud KMS.

  • KEY_ID: il nome della chiave Cloud KMS.

  • KMS_KEY: Chiave Cloud KMS (KEK) in questo formato:

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

    Ecco un esempio di chiave Cloud KMS:

    'gcp-kms://projects/myProject/locations/us/keyRings/myKeyRing/cryptoKeys/myKeyName'
    
  • KMS_KEY_SHORT: simile a KMS_KEY, ma in questo formato:

    projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEY_RING_ID/cryptoKeys/KEY_ID
  • KEYSET_DECODED: Un keyset decodificato come sequenza BYTES. L'output è simile a quello di un keyset wrapped decodificato.

    Sebbene le funzioni keyset restituiscano keyset come byte, l'output dell'utente viene visualizzato come stringa codificata. Per convertire un keyset codificato in un keyset decodificato, consulta Decodificare un keyset Cloud KMS.

  • KEYSET_ENCODED: un keyset codificato come STRING. L'output è simile a quello di un keyset con wrapping codificato.

    Per convertire un keyset codificato in un keyset decodificato, consulta Decodificare un keyset Cloud KMS.

  • WRAPPED_KEYSET_DECODED: Un keyset con wrapping decodificato come sequenza BYTES. Ecco un esempio dell'output:

    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\...'
    

    Sebbene le funzioni di keyset wrapping restituiscano keyset wrapping come byte, l'output dell'utente viene visualizzato come stringa codificata. Per convertire un keyset con wrapping codificato in un keyset con wrapping decodificato, vedi Decodifica un keyset Cloud KMS.

  • WRAPPED_KEYSET_ENCODED: Un keyset con wrapping codificato come STRING. Ecco un esempio dell'output:

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

    Per convertire un keyset con wrapping codificato in un keyset con wrapping decodificato, vedi Decodifica un keyset Cloud KMS.

Gestione delle chiavi

Le sezioni seguenti contengono attività comuni che puoi eseguire con le chiavi Cloud KMS.

Crea un set di chiavi

Puoi creare keyset con wrapping o keyset non elaborati. Per farlo, completa i passaggi nelle sezioni seguenti.

Crea un set di chiavi non elaborato

Esegui la seguente query per creare un keyset con una chiave di tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

SELECT KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') AS raw_keyset

Crea un set di chiavi con wrapping

Esegui la seguente query per creare un keyset Cloud KMS con wrapping con una chiave di tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

SELECT KEYS.NEW_WRAPPED_KEYSET(
  KMS_KEY,
  'DETERMINISTIC_AEAD_AES_SIV_CMAC_256')

Decodificare un set di chiavi

Sebbene le funzioni SQL che restituiscono keyset producano i keyset in formato BYTES, il risultato visualizzato dall'utente viene codificato e visualizzato in formato STRING. Se vuoi convertire questa stringa codificata in una sequenza di byte decodificata che puoi utilizzare come funzioni di crittografia delle chiavi letterali, utilizza la seguente query.

Decodificare un set di chiavi con wrapping

Esegui la seguente query per decodificare un keyset sottoposto a wrapping di Cloud KMS.

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

Decodificare un keyset non elaborato

Esegui la seguente query per decodificare un keyset non elaborato.

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

Eseguire nuovamente il wrapping di un insieme di chiavi con wrapping

Esegui la seguente query per eseguire il wrapping di un keyset sottoposto a wrapping Cloud KMS con una nuova chiave Cloud KMS. KMS_KEY_CURRENT rappresenta il nuovo KMS_KEY utilizzato per criptare il keyset. KMS_KEY_NEW rappresenta il nuovo KMS_KEY utilizzato per criptare il keyset.

SELECT KEYS.REWRAP_KEYSET(
  KMS_KEY_CURRENT,
  KMS_KEY_NEW,
  WRAPPED_KEYSET_DECODED)

Ruotare un set di chiavi con wrapping

Esegui la seguente query per ruotare un keyset Cloud KMS sottoposto a wrapping con una chiave di tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

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

Genera un keyset non elaborato da un keyset con wrapping

Alcune funzioni di crittografia richiedono un keyset non elaborato. Per decriptare un keyset sottoposto a wrapping Cloud KMS per produrre un keyset non elaborato, completa i seguenti passaggi.

  1. Crea un set di chiavi con wrapping.

  2. Nello strumento a riga di comando bq, inserisci i seguenti comandi per salvare un keyset sottoposto a wrapping in un file denominato keyset_to_unwrap, decriptare il keyset sottoposto a wrapping e produrre l'output nel formato 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 ' ' '\'

Genera un set di chiavi con wrapping da un set di chiavi non elaborato

Alcune funzioni di crittografia richiedono un keyset Cloud KMS. Per criptare un keyset non elaborato per produrre un keyset sottoposto a wrapping, completa i seguenti passaggi.

  1. Crea un keyset non elaborato.

  2. Nello strumento a riga di comando bq, inserisci i seguenti comandi per salvare un keyset non elaborato in un file denominato keyset_to_wrap, criptare il keyset non elaborato e produrre l'output nel formato 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 ' ' '\'

Generare una chiave con wrapping per una funzione DLP

Per le funzioni DLP, devi utilizzare una chiave crittografica per ottenere una chiave con wrapping.

  1. Per generare una nuova chiave crittografica, nella riga di comando, esegui questo comando. Le dimensioni della chiave possono essere 16, 24 o 32 byte. L'esempio seguente utilizza una chiave di 16 byte:

    openssl rand 16 > rand.key.16.bin
    
  2. Esegui il wrapping della chiave di 16 byte generata con una chiave KMS. Vedi il seguente esempio:

    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. Ora puoi ottenere il letterale BYTES della chiave sottoposta a wrapping o il formato base64 della chiave sottoposta a wrapping.

    • Valore letterale byte

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

      L'output è simile al seguente:

      \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
      
    • Formato Base64

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

      L'output è simile al seguente:

      CiQA1W20a6Y5elj6xUMn4u4xPwwYVmchVmgKHhCCjSS3yNkMTpsSOQDz5Jg3vAfguw6KaZY0gP/Dh0NnKrcd6ARn9am5WzKppmp/DwW4JGGJTt8jHbNS4EjbtpD/p4SNmw==
      

Ottenere il numero di chiavi in un keyset

Esegui la seguente query per ottenere il numero di chiavi in un keyset non elaborato.

  1. Se utilizzi un keyset sottoposto a wrapping, prima genera un keyset non elaborato.

  2. Esegui questa query con il keyset non elaborato:

    SELECT KEYS.KEYSET_LENGTH(KEYSET_DECODED) as key_count;

Ottenere una rappresentazione JSON di un keyset

Esegui la seguente query per visualizzare una rappresentazione JSON di un keyset non elaborato.

  1. Se utilizzi un keyset sottoposto a wrapping, prima genera un keyset non elaborato.

  2. Esegui questa query con il keyset non elaborato:

    SELECT KEYS.KEYSET_TO_JSON(KEYSET_DECODED);

Crittografia e decrittografia

Puoi utilizzare keyset non elaborati o keyset sottoposti a wrapping per criptare una colonna di una tabella. Puoi anche scegliere di utilizzare la crittografia deterministica o non deterministica nelle colonne. Gli esempi in questa sezione utilizzano i keyset sottoposti a wrapping, ma puoi sostituirli con keyset non elaborati.

Criptare in modo deterministico una colonna con un keyset sottoposto a wrapping

Esegui la seguente query per creare una tabella e archiviare un keyset Cloud KMS sottoposto a wrapping con crittografia deterministica in una colonna denominata encrypted_content.

  1. Crea un set di chiavi con wrapping.

  2. Cripta una colonna con il keyset sottoposto a wrapping.

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

Decriptare in modo deterministico una colonna con un keyset sottoposto a wrapping

Esegui la seguente query per decriptare in modo deterministico una colonna che contiene contenuti criptati, utilizzando un keyset con wrapping Cloud KMS. Questa query presuppone che tu faccia riferimento a una tabella con una colonna denominata encrypted_content.

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

Criptare in modo non deterministico una colonna con un keyset sottoposto a wrapping

Consulta Criptare in modo deterministico una colonna con un keyset sottoposto a wrapping, ma sostituisci DETERMINISTIC_ENCRYPT con AEAD.ENCRYPT. Assicurati che il tuo keyset sia di tipo AEAD_AES_GCM_256.

Decriptare in modo non deterministico una colonna con un keyset sottoposto a wrapping

Consulta la sezione Decriptare in modo deterministico una colonna con un keyset sottoposto a wrapping, ma sostituisci DETERMINISTIC_DECRYPT_STRING con AEAD.DECRYPT_STRING. Assicurati che il keyset sia di tipo AEAD_AES_GCM_256.

Passaggi successivi

  • Scopri di più su Cloud KMS. Questo argomento include informazioni concettuali sulla crittografia a livello di colonna per Google Cloud.
  • Scopri di più sulla crittografia AEAD per BigQuery. Questo argomento include informazioni concettuali sulla crittografia a livello di colonna specificamente per BigQuery.
  • Scopri di più sulle funzioni di crittografia AEAD per BigQuery. Questo argomento contiene tutte le funzioni SQL che puoi utilizzare per la crittografia a livello di colonna in BigQuery.