Encriptação ao nível da coluna com o Cloud KMS

Pode usar o Cloud Key Management Service (Cloud KMS) para encriptar as chaves que, por sua vez, encriptam os valores nas tabelas do BigQuery. Pode usar as funções de encriptação AEAD com conjuntos de chaves do Cloud KMS ou conjuntos de chaves envolvidos para fornecer uma segunda camada de proteção ao nível da coluna.

Introdução

Para oferecer uma camada adicional de proteção, o Cloud KMS encripta a sua chave de encriptação de dados (DEK) com uma segunda chave de encriptação de chaves (KEK). No BigQuery, a referência a um conjunto de chaves encriptado em vez de um conjunto de chaves de texto simples ajuda a reduzir o risco de exposição de chaves. A KEK é um conjunto de chaves de encriptação simétricas que é armazenado em segurança no Cloud KMS e gerido através de funções e autorizações da gestão de identidade e de acesso (IAM).

O BigQuery suporta funções de encriptação determinísticas e não determinísticas. Com a encriptação determinística, se os fragmentos de dados armazenados e os dados autenticados adicionais (opcional) forem idênticos, o texto cifrado é idêntico. Isto permite o suporte de agregação e junções com base na coluna encriptada. Com a encriptação não determinística, o texto cifrado armazenado é único, independentemente dos dados encriptados, o que impede a agrupamento, a agregação e as junções.

No momento da execução da consulta, fornece o caminho do recurso do Cloud KMS da KEK e o texto cifrado da DEK envolvida. O BigQuery chama o Cloud KMS para desembrulhar a DEK e, em seguida, usa essa chave para desencriptar os dados na sua consulta. A versão não envolvida da DEK só é armazenada na memória durante a consulta e, em seguida, é destruída.

Se usar o Cloud KMS numa região onde o Cloud External Key Manager é suportado, pode usar chaves baseadas no Cloud EKM no Cloud KMS.

Exemplos de utilização

Os exemplos de utilização da encriptação com chaves do Cloud KMS incluem o seguinte:

  • Dados encriptados externamente que precisam de ser armazenados no BigQuery sem armazenar o conjunto de chaves em texto simples. Em seguida, pode exportar os dados da tabela ou desencriptá-los com uma consulta SQL.
  • "Controlo de acesso duplo" em dados encriptados no BigQuery. Um utilizador tem de ter autorização para aceder à tabela e à chave de encriptação para ler dados em texto não cifrado.
Matriz de autorizações do utilizador
Autorização na tabela Sem autorização na tabela
Autorizações na chave Ler e desencriptar dados encriptados. Sem acesso.
Sem autorizações na chave Ler dados encriptados. Sem acesso.

Se um utilizador tiver autorização para aceder à chave do KMS e tiver acesso ao conjunto de chaves encapsulado, as funções SQL podem desencapsular o conjunto de chaves e desencriptar o texto cifrado. Os utilizadores também podem usar a API REST ou a CLI do Cloud KMS para desembrulhar o conjunto de chaves.
O exemplo de consulta seguinte usa funções SQL do KMS para desencriptar texto cifrado não determinístico:

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

Exemplo de utilização

Suponha uma implementação em que os códigos postais são considerados informações confidenciais. Os dados de códigos postais podem ser inseridos na tabela do BigQuery através da função de encriptação AEAD, encriptando assim a coluna Zipcode. Neste exemplo, usamos a função AEAD.ENCRYPT com a função de gestão do conjunto de chaves envolvido. A função KEYS.KEYSET_CHAINdesencripta a chave de encriptação digital com a KEK e a função AEAD.ENCRYPTtransmite as informações ao KMS.

A cadeia de conjuntos de chaves para encriptação e desencriptação garante que a chave de encriptação de dados (DEK) é encriptada ou envolvida com uma KEK e transmitida com essa KEK. A DEK envolvida é desencriptada ou desembrulhada na função SQL e, em seguida, usada para encriptar ou desencriptar dados.

A função não determinística AEAD pode desencriptar dados quando estes são acedidos através da função na consulta que está a ser executada na tabela.

imagem

A função determinística AEAD pode desencriptar dados quando são acedidos através da função na consulta que está a ser executada na tabela e suporta a agregação e as junções com os dados encriptados.

imagem

Sintaxe de função não determinística

A sintaxe suportada para usar funções não determinísticas inclui o seguinte:

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)

Consulte a sintaxe das funções AEAD.DECRYPT_BYTES, AEAD.ENCRYPT, AEAD.DECRYPT_STRING e KEYS.KEYSET_CHAIN.

Sintaxe de função determinística

A sintaxe suportada para usar funções determinísticas inclui o seguinte:

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)

Consulte a sintaxe das funções DETERMINISTIC_DECRYPT_BYTES, DETERMINISTIC_ENCRYPT, DETERMINISTIC_DECRYPT_STRING e KEYS.KEYSET_CHAIN.

Funções e permissões

Para ver uma lista de funções do Cloud KMS, consulte o artigo Autorizações e funções do Cloud KMS.

Limitações

A encriptação com o Cloud KMS tem as seguintes limitações e restrições:

  • As chaves do Cloud KMS estão restritas à mesma região ou multirregião que a consulta. A utilização de chaves globais do Cloud KMS não é permitida por motivos de fiabilidade.

  • Não é possível rodar um conjunto de chaves envolvido através da função KEYS.ROTATE_KEYSET.

  • Os parâmetros constantes numa consulta do BigQuery são visíveis para os utilizadores no plano de consulta de diagnóstico. Este fator pode afetar os parâmetros kms_resource_name e first_level_keyset da função KEYSET_CHAIN. As chaves nunca são expostas em texto simples, e é necessária autorização para a chave do Cloud KMS para desencriptar o conjunto de chaves envolvido. Esta abordagem garante que as chaves não são expostas através do plano de consulta de diagnóstico, a menos que o utilizador tenha autorização para desencriptar o conjunto de chaves.

  • A encriptação ao nível da coluna tem as seguintes limitações quando usada com classificações de segurança baseadas em tipos:

    • Segurança ao nível da coluna: os utilizadores só podem desencriptar ou encriptar dados em colunas às quais têm autorização de acesso.

    • Segurança ao nível da linha: os utilizadores só podem desencriptar dados em linhas às quais têm permissão de acesso.

  • As funções SQL ao nível da coluna não têm um impacto significativo no desempenho quando comparadas com o desempenho das funções de encriptação não processadas, em que os dados das chaves são enviados em texto simples.

Antes de começar

Para trabalhar com chaves, conjuntos de chaves, tabelas encriptadas, funções determinísticas e não determinísticas do Cloud KMS, tem de fazer o seguinte, se ainda não o tiver feito:

  1. Crie um Google Cloud projeto.

  2. Crie um conjunto de dados do BigQuery.

  3. Crie um conjunto de chaves do Cloud KMS.

  4. Crie uma chave do Cloud KMS para uma coluna encriptada com o software ou o nível de proteção do Hardware Security Module (HSM).

  5. Conceda autorizações ao utilizador para trabalhar com chaves do Cloud KMS, encriptação e desencriptação.

Tenha em atenção os seguintes conceitos, uma vez que são referidos nas secções seguintes:

  • PROJECT_ID: o nome do projeto do Google Cloud.

  • DATASET_NAME: o nome do conjunto de dados do BigQuery.

  • LOCATION_ID: a localização do conjunto de dados do BigQuery.

  • TABLE_NAME: o nome da tabela do BigQuery.

  • KEY_RING_ID: o nome do conjunto de chaves do Cloud KMS.

  • KEY_ID: o nome da chave do Cloud KMS.

  • KMS_KEY: chave do Cloud KMS (KEK) neste formato:

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

    Segue-se um exemplo de uma chave do Cloud KMS:

    'gcp-kms://projects/myProject/locations/us/keyRings/myKeyRing/cryptoKeys/myKeyName'
    
  • KMS_KEY_SHORT: semelhante a KMS_KEY, mas neste formato:

    projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEY_RING_ID/cryptoKeys/KEY_ID
  • KEYSET_DECODED: um conjunto de chaves descodificado como uma sequência BYTES. A saída é semelhante à de um conjunto de chaves envolvido descodificado.

    Embora as funções de conjunto de chaves devolvam conjuntos de chaves como bytes, o resultado para o utilizador é apresentado como uma string codificada. Para converter um conjunto de chaves codificado num conjunto de chaves descodificado, consulte o artigo Descodificar um conjunto de chaves do Cloud KMS

  • KEYSET_ENCODED: um conjunto de chaves codificado como um STRING. O resultado é semelhante ao de um conjunto de chaves envolvido codificado.

    Para converter um conjunto de chaves codificado num conjunto de chaves descodificado, consulte o artigo Descodificar um conjunto de chaves do Cloud KMS

  • WRAPPED_KEYSET_DECODED: um conjunto de chaves envolvido descodificado como uma sequência BYTES. Segue-se um exemplo do aspeto do resultado:

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

    Embora as funções de conjunto de chaves envolvidas devolvam conjuntos de chaves envolvidas como bytes, o resultado do utilizador é apresentado como uma string codificada. Para converter um conjunto de chaves envolvido codificado num conjunto de chaves envolvido descodificado, consulte o artigo Descodificar um conjunto de chaves do Cloud KMS

  • WRAPPED_KEYSET_ENCODED: um conjunto de chaves envolvido codificado como STRING. Segue-se um exemplo do aspeto do resultado:

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

    Para converter um conjunto de chaves envolvido codificado num conjunto de chaves envolvido descodificado, consulte o artigo Descodificar um conjunto de chaves do Cloud KMS

Gestão de chaves

As secções seguintes contêm tarefas comuns que pode realizar com as chaves do Cloud KMS.

Crie um conjunto de chaves

Pode criar conjuntos de chaves envolvidos ou conjuntos de chaves não processados. Para o fazer, conclua os passos nas secções seguintes.

Crie um conjunto de chaves não processado

Execute a seguinte consulta para criar um conjunto de chaves com uma chave do tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

SELECT KEYS.NEW_KEYSET('DETERMINISTIC_AEAD_AES_SIV_CMAC_256') AS raw_keyset

Crie um conjunto de chaves envolvido

Execute a seguinte consulta para criar um conjunto de chaves envolvido do Cloud KMS com uma chave do tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

SELECT KEYS.NEW_WRAPPED_KEYSET(
  KMS_KEY,
  'DETERMINISTIC_AEAD_AES_SIV_CMAC_256')

Descodifique um conjunto de teclas

Embora as funções SQL que devolvem conjuntos de chaves produzam os conjuntos de chaves no formato BYTES, o resultado apresentado ao utilizador é codificado e apresentado no formato STRING. Se quiser converter esta string codificada numa sequência de bytes descodificada que pode usar como funções de encriptação de chaves literais, use a seguinte consulta.

Descodifique um conjunto de chaves envolvido

Execute a seguinte consulta para descodificar um conjunto de chaves envolvido do Cloud KMS.

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

Descodifique um conjunto de chaves não processado

Execute a seguinte consulta para descodificar um conjunto de chaves não processado.

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

Volte a encapsular um conjunto de chaves encapsulado

Execute a seguinte consulta para voltar a encapsular um conjunto de chaves encapsulado do Cloud KMS com uma nova chave do Cloud KMS. KMS_KEY_CURRENT representa o novo KMS_KEY que é usado para encriptar o conjunto de chaves. KMS_KEY_NEW representa o novo KMS_KEY que é usado para encriptar o conjunto de chaves.

SELECT KEYS.REWRAP_KEYSET(
  KMS_KEY_CURRENT,
  KMS_KEY_NEW,
  WRAPPED_KEYSET_DECODED)

Alterne um conjunto de chaves envolvido

Execute a seguinte consulta para alternar um conjunto de chaves envolvidas do Cloud KMS com uma chave do tipo DETERMINISTIC_AEAD_AES_SIV_CMAC_256.

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

Gere um conjunto de chaves não processado a partir de um conjunto de chaves processado

Algumas funções de encriptação requerem um conjunto de chaves não processadas. Para desencriptar um conjunto de chaves envolvido do Cloud KMS para produzir um conjunto de chaves não processado, conclua os passos seguintes.

  1. Crie um conjunto de chaves envolvido.

  2. Na ferramenta de linhas de comando bq, introduza os seguintes comandos para guardar um conjunto de chaves envolvido num ficheiro denominado keyset_to_unwrap, desencriptar o conjunto de chaves envolvido e produzir o resultado no 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 ' ' '\'

Gere um conjunto de chaves envolvido a partir de um conjunto de chaves não processado

Algumas funções de encriptação requerem um conjunto de chaves envolvido do Cloud KMS. Para encriptar um conjunto de chaves não processado para produzir um conjunto de chaves envolvido, conclua os seguintes passos.

  1. Crie um conjunto de chaves não processadas.

  2. Na ferramenta de linhas de comando bq, introduza os seguintes comandos para guardar um conjunto de chaves não processado num ficheiro denominado keyset_to_wrap, encriptar o conjunto de chaves não processado e produzir o resultado no 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 ' ' '\'

Gere uma chave envolvida para uma função de DLP

Para as funções de DLP, precisa de uma chave criptográfica e, em seguida, usa essa chave para obter uma chave envolvida.

  1. Para gerar uma nova chave criptográfica, na linha de comandos, execute o seguinte comando. O tamanho da chave pode ser de 16, 24 ou 32 bytes. O exemplo seguinte usa uma chave de 16 bytes:

    openssl rand 16 > rand.key.16.bin
    
  2. Encapsule a chave de 16 bytes gerada com uma chave do KMS. Veja o exemplo seguinte:

    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. Agora, pode obter o literal BYTES da chave envolvida ou o formato base64 da chave envolvida.

    • Literal de bytes

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

      O resultado tem o seguinte aspeto:

      \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
      

      O resultado tem o seguinte aspeto:

      CiQA1W20a6Y5elj6xUMn4u4xPwwYVmchVmgKHhCCjSS3yNkMTpsSOQDz5Jg3vAfguw6KaZY0gP/Dh0NnKrcd6ARn9am5WzKppmp/DwW4JGGJTt8jHbNS4EjbtpD/p4SNmw==
      

Obtenha o número de chaves num conjunto de chaves

Execute a seguinte consulta para obter o número de chaves num conjunto de chaves não processado.

  1. Se estiver a trabalhar com um conjunto de chaves envolvido, primeiro, gere um conjunto de chaves não processado.

  2. Execute esta consulta com o conjunto de chaves não processado:

    SELECT KEYS.KEYSET_LENGTH(KEYSET_DECODED) as key_count;

Obtenha uma representação JSON de um conjunto de chaves

Execute a seguinte consulta para ver uma representação JSON de um conjunto de chaves não processado.

  1. Se estiver a trabalhar com um conjunto de chaves envolvido, primeiro, gere um conjunto de chaves não processado.

  2. Execute esta consulta com o conjunto de chaves não processado:

    SELECT KEYS.KEYSET_TO_JSON(KEYSET_DECODED);

Encriptação e desencriptação

Pode usar conjuntos de chaves não processados ou conjuntos de chaves envolvidos para encriptar uma coluna numa tabela. Também pode optar por usar a encriptação determinística ou não determinística nas suas colunas. Os exemplos nesta secção usam conjuntos de chaves envolvidos, mas pode substituir os conjuntos de chaves envolvidos por conjuntos de chaves não processados.

Encriptar deterministicamente uma coluna com um conjunto de chaves envolvido

Execute a seguinte consulta para criar uma tabela e armazenar um conjunto de chaves envolvidas do Cloud KMS com encriptação determinística numa coluna denominada encrypted_content.

  1. Crie um conjunto de chaves envolvido.

  2. Encriptar uma coluna com o conjunto de chaves envolvido.

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

Desencriptar deterministicamente uma coluna com um conjunto de chaves envolvido

Execute a seguinte consulta para desencriptar deterministicamente uma coluna que contém conteúdo encriptado, usando um conjunto de chaves envolvidas do Cloud KMS. Esta consulta pressupõe que está a referenciar uma tabela com uma coluna denominada encrypted_content.

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

Encriptar não deterministicamente uma coluna com um conjunto de chaves envolvido

Consulte o artigo Encriptar deterministicamente uma coluna com um conjunto de chaves envolvido, mas substitua DETERMINISTIC_ENCRYPT por AEAD.ENCRYPT. Certifique-se de que o conjunto de chaves é do tipo AEAD_AES_GCM_256.

Descriptografe não deterministicamente uma coluna com um conjunto de chaves envolvido

Consulte o artigo Descriptografe deterministicamente uma coluna com um conjunto de chaves envolvido, mas substitua DETERMINISTIC_DECRYPT_STRING por AEAD.DECRYPT_STRING. Certifique-se de que o conjunto de chaves é do tipo AEAD_AES_GCM_256.

O que se segue?

  • Saiba mais sobre o Cloud KMS. Este tópico inclui informações conceptuais sobre a encriptação ao nível da coluna para o Google Cloud.
  • Saiba mais acerca da encriptação AEAD para o BigQuery. Este tópico inclui informações conceptuais sobre a encriptação ao nível da coluna, especificamente para o BigQuery.
  • Saiba mais sobre as funções de encriptação AEAD para o BigQuery. Este tópico contém todas as funções SQL que pode usar para a encriptação ao nível da coluna no BigQuery.