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 set di chiavi o i set di chiavi con 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 set di chiavi criptato anziché a un set di chiavi in testo non crittografato consente di ridurre il rischio di esposizione delle chiavi. La KEK è un set di chiavi di crittografia simmetrica archiviato in modo sicuro in Cloud KMS e gestito utilizzando i ruoli e le autorizzazioni di 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, il testo crittografato è identico. Ciò consente il supporto di aggregazione e join in base alla colonna criptata. Con la crittografia non deterministica, il testo crittografato 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 crittografato della DEK con wrapping. BigQuery chiama Cloud KMS per annullare il wrapping della DEK, quindi utilizza la chiave per decriptare i dati nella query. La versione senza wrapping della DEK viene archiviata in memoria solo per la durata della query, quindi 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 i seguenti:

  • Dati criptati esternamente che devono essere archiviati in BigQuery senza archiviare il set di chiavi in testo non crittografato. I dati possono quindi essere esportati dalla tabella o decriptati con una query SQL.
  • "Doppio controllo dell'accesso" sui dati criptati in BigQuery. A un utente deve essere concessa l'autorizzazione sia per la tabella sia per la chiave di crittografia per leggere i dati in testo in chiaro.
Matrice di autorizzazioni dell'utente
Autorizzazione nella tabella Nessuna autorizzazione nella tabella
Autorizzazioni sulla chiave Leggere e decriptare i dati criptati. Nessun accesso.
Nessuna autorizzazione sulla chiave Lettura di dati criptati. Nessun accesso.

Se un utente ha l'autorizzazione ad accedere alla chiave KMS e ha accesso al set di chiavi con wrapping, le funzioni SQL possono annullare il wrapping del set di chiavi e decriptare il testo crittografato. Gli utenti possono anche utilizzare l'API REST o l'CLI di Cloud KMS per annullare il wrapping del set di chiavi.
Il seguente esempio di query utilizza le funzioni SQL KMS per decriptare il testo crittografato 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 che i codici postali siano considerati informazioni sensibili. I dati relativi al codice postale possono essere inseriti nella tabella BigQuery utilizzando la funzione di crittografia AEAD, così da criptare la colonna Zipcode. In questo esempio, utilizziamo la funzione AEAD.ENCRYPT con la funzione di gestione del set di chiavi con wrapping. La funzione KEYS.KEYSET_CHAIN cripta la chiave di crittografia digitale con la KEK, mentre la funzione AEAD.ENCRYPT passa le informazioni al KMS.

La catena di set di chiavi per la crittografia e la decrittografia assicura che la chiave di crittografia dei dati (DEK) sia criptata o sottoposta a wrapping con una KEK e passata insieme a questa KEK. La DEK con wrapping viene decriptata o decriptata 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 in esecuzione nella tabella.

immagine

La funzione deterministica AEAD può decriptare i dati quando vi si accede utilizzando la funzione nella query in esecuzione nella tabella e supporta l'aggregazione e le unioni utilizzando i dati criptati.

immagine

Sintassi delle funzioni non deterministiche

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 delle funzioni deterministiche

La sintassi supportata per l'utilizzo delle 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, vedi Autorizzazioni e ruoli 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 regione della query. L'utilizzo di chiavi Cloud KMS globali non è consentito per motivi di affidabilità.

  • Non è possibile ruotare un set di chiavi con wrapping utilizzando la funzione KEYS.ROTATE_KEYSET.

  • I parametri della costante in una query BigQuery sono visibili agli utenti nel piano di query diagnostica. Questo fattore può influenzare i parametri kms_resource_name e first_level_keyset della funzione KEYSET_CHAIN. Le chiavi non vengono mai esposte in testo non crittografato e per decriptare il set di chiavi con wrapping è necessaria l'autorizzazione per la chiave Cloud KMS. Questo approccio garantisce che le chiavi non vengano esposte tramite il piano di query di diagnostica, a meno che l'utente non abbia l'autorizzazione per decriptare il set di chiavi.

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

    • Sicurezza a livello di colonna: gli utenti possono decriptare o criptare solo i dati sulle colonne a cui sono autorizzati ad accedere.

    • Sicurezza a livello di riga: gli utenti possono decriptare solo i dati presenti nelle righe a cui sono autorizzati ad accedere.

  • 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 utilizzare le chiavi, i set di chiavi, le tabelle criptate e le funzioni deterministiche e non deterministiche di Cloud KMS, devi procedere come segue:

  1. Crea un progetto Google Cloud.

  2. Crea un set di dati BigQuery.

  3. Crea un keyring di Cloud KMS.

  4. Crea una chiave Cloud KMS per una colonna criptata con il livello di protezione software o HSM (Hardware Security Module).

  5. Concedi agli utenti le autorizzazioni per utilizzare chiavi, crittografia e decriptazione di Cloud KMS.

Prendi nota dei seguenti concetti, a cui vengono riportati 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 del keyring Cloud KMS.

  • KEY_ID: il nome della chiave Cloud KMS.

  • KMS_KEY: chiave Cloud KMS (KEK) nel 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 nel seguente formato:

    projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEY_RING_ID/cryptoKeys/KEY_ID
    
  • KEYSET_DECODED: un set di tasti decodificato come sequenza BYTES. L'output è simile a quello di un set di chiavi con wrapping decodificato.

    Anche se le funzioni del set di tasti restituiscono i set di tasti sotto forma di byte, l'output utente viene visualizzato come stringa codificata. Per convertire un set di chiavi codificato in un set di chiavi decodificato, consulta Decodificare un set di chiavi Cloud KMS.

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

    Per convertire un set di chiavi codificato in un set di chiavi decodificato, consulta Decodificare un set di chiavi Cloud KMS.

  • WRAPPED_KEYSET_DECODED: un set di chiavi con wrapping decodificato come sequenza BYTES. Ecco un esempio di come appare l'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 del set di chiavi con wrapping restituiscano set di chiavi con wrapping come byte, l'output utente viene visualizzato come stringa codificata. Per convertire un set di chiavi con wrapping codificato in un set di chiavi con wrapping decodificato, consulta Decodificare un set di chiavi Cloud KMS

  • WRAPPED_KEYSET_ENCODED: un set di chiavi con wrapping codificato come STRING. Ecco un esempio di come appare l'output:

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

    Per convertire un set di chiavi con wrapping codificato in un set di chiavi con wrapping decodificato, consulta Decodificare un set di chiavi con wrapping Cloud KMS

Gestione delle chiavi

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

Crea un set di chiavi

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

Crea un set di chiavi non elaborato

Esegui la query seguente per creare un set di chiavi 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 query seguente per creare un set di chiavi con wrapping Cloud KMS 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

Anche se le funzioni SQL che restituiscono set di chiavi producono i set di tasti in formato BYTES, il risultato visualizzato dall'utente è 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 chiave letterale, utilizza la seguente query.

Decodifica di un set di chiavi con wrapping

Esegui la query seguente per decodificare un set di chiavi con wrapping di Cloud KMS.

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

Decodifica un set di chiavi non elaborato

Esegui la query seguente per decodificare un set di chiavi non elaborato.

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

Riavvolgimento di un set di chiavi con wrapping

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

SELECT KEYS.REWRAP_KEYSET(
  KMS_KEY_CURRENT,
  KMS_KEY_NEW,
  WRAPPED_KEYSET_DECODED)

Ruota un set di chiavi con wrapping

Esegui la query seguente per ruotare un set di chiavi con wrapping di Cloud KMS 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 set di chiavi non elaborato da un set di chiavi con wrapping

Alcune funzioni di crittografia richiedono un set di chiavi non elaborato. Per decriptare un set di chiavi con wrapping di Cloud KMS e generare un set di chiavi non elaborato, completa i passaggi seguenti.

  1. Crea un set di chiavi con wrapping.

  2. Nello strumento a riga di comando bq, inserisci i comandi seguenti per salvare un set di chiavi con wrapping in un file denominato keyset_to_unwrap, decriptare il set di chiavi con 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 set di chiavi con wrapping Cloud KMS. Per criptare un set di chiavi non elaborato in modo da produrre un set di chiavi con wrapping, completa i seguenti passaggi.

  1. Crea un set di chiavi non elaborato.

  2. Nello strumento a riga di comando bq, inserisci i comandi seguenti per salvare un set di chiavi non elaborato in un file denominato keyset_to_wrap, cripta il set di chiavi non elaborato e genera 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 disporre di una chiave di crittografia, quindi utilizzarla per ottenere una chiave con wrapping.

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

    openssl rand 16 > rand.key.16.bin
    
  2. Esegui il wrapping della chiave a 16 byte generata con una chiave KMS. Vedi l'esempio che segue:

    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 valore letterale BYTES della chiave con wrapping o il formato base64 della chiave con wrapping.

    • Byte letterale

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

      L'output sarà 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 sarà simile al seguente:

      CiQA1W20a6Y5elj6xUMn4u4xPwwYVmchVmgKHhCCjSS3yNkMTpsSOQDz5Jg3vAfguw6KaZY0gP/Dh0NnKrcd6ARn9am5WzKppmp/DwW4JGGJTt8jHbNS4EjbtpD/p4SNmw==
      

Recuperare il numero di chiavi in un set di chiavi

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

  1. Se stai utilizzando un set di chiavi con wrapping, per prima cosa genera un set di chiavi non elaborato.

  2. Esegui questa query con il set di chiavi non elaborato:

    SELECT KEYS.KEYSET_LENGTH(KEYSET_DECODED) as key_count;
    

Ottenere una rappresentazione JSON di un set di chiavi

Esegui questa query per visualizzare una rappresentazione JSON di un set di chiavi non elaborato.

  1. Se stai utilizzando un set di chiavi con wrapping, per prima cosa genera un set di chiavi non elaborato.

  2. Esegui questa query con il set di chiavi non elaborato:

    SELECT KEYS.KEYSET_TO_JSON(KEYSET_DECODED);
    

Crittografia e decrittografia

Puoi utilizzare set di chiavi non elaborati o con wrapping per criptare una colonna in una tabella. Puoi anche scegliere di utilizzare la crittografia deterministica o non deterministica sulle tue colonne. Gli esempi in questa sezione utilizzano set di chiavi con wrapping, ma puoi sostituire quelli con wrapping con set di chiavi non elaborati.

Cripta in modo determinato una colonna con un set di chiavi con wrapping

Esegui la query seguente per creare una tabella e archiviare un set di chiavi con wrapping di Cloud KMS con crittografia deterministica in una colonna denominata encrypted_content.

  1. Crea un set di chiavi con wrapping.

  2. Cripta una colonna con il set di chiavi con 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
    

Decripta in modo determinato una colonna con un set di chiavi con wrapping

Esegui la seguente query per decriptare in modo deterministico una colonna che contiene contenuti criptati utilizzando un set di chiavi 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 set di chiavi con wrapping

Consulta Criptare in modo determinato una colonna con un set di chiavi con wrapping, ma sostituire DETERMINISTIC_ENCRYPT con AEAD.ENCRYPT. Assicurati che il tuo set di chiavi sia di tipo AEAD_AES_GCM_256.

Decriptare in modo non deterministico una colonna con un set di chiavi con wrapping

Consulta Decriptare una colonna in modo determinato con un set di chiavi con wrapping, ma sostituisci DETERMINISTIC_DECRYPT_STRING con AEAD.DECRYPT_STRING. Assicurati che il tuo set di chiavi 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 specifica 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.