Criptografia no nível da coluna com o Cloud KMS

Use o Cloud Key Management Service (Cloud KMS) para criptografar as chaves que, por sua vez, criptografam os valores nas tabelas do BigQuery. É possível usar as funções de criptografia AEAD com os conjuntos de chaves ou conjuntos de chaves encapsulados do Cloud KMS para fornecer uma segunda camada de proteção no nível da coluna.

Introdução

Para fornecer uma camada extra de proteção, o Cloud KMS criptografa sua chave de criptografia de dados (DEK) com uma segunda chave de criptografia de chaves (KEK). No BigQuery, fazer referência a um conjunto de chaves criptografado em vez de um texto simples ajuda a reduzir o risco de exposição da chave. A KEK é um conjunto de chaves de criptografia simétrica armazenada com segurança no Cloud KMS e gerenciada por papéis e permissões de gerenciamento de identidade e acesso (IAM).

O BigQuery é compatível com funções de criptografia determinísticas e não determinísticas. Com a criptografia determinística, se os dados armazenados e os dados autenticados adicionais (opcional) forem idênticos, o texto criptografado será idêntico. Isso permite compatibilidade com agregação e mesclagens com base na coluna criptografada. Com a criptografia não determinística, o texto criptografado armazenado é exclusivo, independentemente dos dados criptografados, o que impede o clustering, a agregação e as junções.

No tempo de execução da consulta, você fornece o caminho do recurso do Cloud KMS para a KEK e o texto criptografado da DEK encapsulada. O BigQuery chama o Cloud KMS para desencapsular a DEK e, em seguida, usa essa chave para descriptografar os dados na consulta. A versão desencapsulada da DEK é armazenada apenas na memória durante a consulta e, em seguida, destruída.

Para usar o Cloud KMS em uma região compatível com o Gerenciador de chaves externas do Cloud, use as chaves baseadas no Cloud EKM no Cloud KMS.

Casos de uso

Os casos de uso de criptografia com chaves do Cloud KMS incluem o seguinte:

  • Dados criptografados externamente que precisam ser armazenados no BigQuery sem armazenar o conjunto de chaves em texto simples. Em seguida, seus dados podem ser exportados da tabela ou descriptografados com uma consulta SQL.
  • "Controle de acesso duplo" sobre dados criptografados no BigQuery. É preciso que um usuário tenha permissão para acessar a tabela e a chave de criptografia e ler dados em texto não criptografado.
Matriz de permissões do usuário
Permissões na tabela Sem permissões na tabela
Permissões na chave Ler e descriptografar dados criptografados. Sem acesso.
Sem permissões na chave Ler dados criptografados. Sem acesso.

Se um usuário tiver permissão para acessar a chave KMS e tiver acesso ao conjunto de chaves encapsulado, as funções SQL poderão desencapsular o conjunto de chaves e descriptografar o texto criptografado. Os usuários também podem usar a API REST ou a CLI do Cloud KMS para separar o conjunto de chaves.
A amostra de consulta a seguir usa funções SQL do KMS para descriptografar um texto criptografado 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 caso de uso

Suponha que uma implementação seja considerada como informações confidenciais. É possível inserir os dados do CEP na tabela do BigQuery usando a função de criptografia AEAD, criptografando a coluna Zipcode. Neste exemplo, usamos a função AEAD.ENCRYPT com a função de gerenciamento de conjunto de chaves encapsulada. A função KEYS.KEYSET_CHAIN criptografa a chave de criptografia digital com a KEK, e a função AEAD.ENCRYPT transmite as informações para o KMS.

A cadeia de conjuntos de chaves para criptografia e descriptografia garante que a chave de criptografia de dados (DEK) seja criptografada ou encapsulada com uma KEK e transmitida com ela. A DEK encapsulada é descriptografada ou desencapsulada na função SQL e, em seguida, usada para criptografar ou descriptografar dados.

A função não determinística AEAD pode descriptografar dados quando eles são acessados usando a função na consulta que está sendo executada na tabela.

imagem

A função determinística de AEAD pode descriptografar dados quando eles são acessados usando a função na consulta que está sendo executada na tabela, além de ser compatível com agregação e mesclagens usando dados criptografados.

imagem

Sintaxe de funções não determinísticas

A sintaxe compatível com o uso de 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 AEAD.DECRYPT_BYTES, AEAD.ENCRYPT, AEAD.DECRYPT_STRING e KEYS.KEYSET_CHAIN.

Sintaxe de função determinística

A sintaxe compatível com o uso de funções determinísticas inclui:

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 DETERMINISTIC_DECRYPT_BYTES, DETERMINISTIC_ENCRYPT, DETERMINISTIC_DECRYPT_STRING e KEYS.KEYSET_CHAIN.

Papéis e permissões

Para acessar uma lista de papéis para o Cloud KMS, consulte Permissões e papéis do Cloud KMS.

Limitações

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

  • As chaves do Cloud KMS são restritas à mesma região ou multirregião que a consulta. O uso de chaves globais do Cloud KMS não é permitido por motivos de confiabilidade.

  • Não é possível girar um conjunto de chaves encapsulado usando a função KEYS.ROTATE_KEYSET.

  • Hoje, os parâmetros constantes de uma consulta do BigQuery ficam visíveis para os usuários no plano de consulta de diagnóstico. Isso 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 a permissão para a chave do Cloud KMS é necessária para descriptografar o conjunto de chaves encapsuladas. Isso garante que as chaves não sejam expostas por meio do plano de consulta de diagnóstico, a menos que o usuário tenha permissão para descriptografar o conjunto de chaves.

  • A criptografia no nível da coluna tem as seguintes limitações quando usada com classificações de segurança baseadas em tipo:

    • Segurança no nível da coluna: os usuários só podem descriptografar ou criptografar dados em colunas que eles podem acessar.

    • Segurança no nível da linha: os usuários só podem descriptografar dados em linhas que eles podem acessar.

  • As funções SQL no nível da coluna não têm impacto significativo no desempenho quando comparadas com o desempenho das funções de criptografia brutas em que os dados principais são enviados em texto simples.

Antes de começar

Para trabalhar com chaves, conjuntos de chaves, tabelas criptografadas, funções determinísticas e não determinísticas do Cloud KMS, é preciso fazer o seguinte:

  1. Crie um projeto do Google Cloud.

  2. crie um conjunto de dados do BigQuery;

  3. Crie um keyring do Cloud KMS.

  4. Crie uma chave do Cloud KMS para uma coluna criptografada com o software ou nível de proteção Módulo de segurança de hardware (HSM, na sigla em inglês).

  5. Conceda permissões do usuário para trabalhar com chaves, criptografia e descriptografia do Cloud KMS.

Confira os conceitos a seguir, conforme referenciados nas próximas seções:

  • PROJECT_ID: o nome do projeto do Google Cloud.

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

  • LOCATION_ID: o local do conjunto de dados do BigQuery.

  • TABLE_NAME: o nome da tabela do BigQuery.

  • KEY_RING_ID: o nome do keyring 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'

    Confira um exemplo de 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 decodificado como uma sequência BYTES. A saída é semelhante a de um conjunto de chaves encapsulado decodificado.

    Embora as funções do conjunto de chaves retornem conjuntos de chaves como bytes, a saída do usuário é exibida como uma string codificada. Para converter um conjunto de chaves codificado em um conjunto de chaves decodificado, consulte Decodificar um conjunto de chaves do Cloud KMS.

  • KEYSET_ENCODED: um conjunto de chaves codificado como um STRING. A saída é semelhante à de um conjunto de chaves encapsuladas codificadas.

    Para converter um conjunto de chaves codificado em um conjunto de chaves decodificado, consulte Decodificar um conjunto de chaves do Cloud KMS.

  • WRAPPED_KEYSET_DECODED: um conjunto de chaves encapsulado decodificado como uma sequência de BYTES. Confira um exemplo de saída:

    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 conjuntos de chaves encapsulados retornem conjuntos de chaves encapsulados como bytes, a saída do usuário é exibida como uma string codificada. Para converter um conjunto de chaves codificado em um conjunto de chaves encapsulado decodificado, consulte Decodificar um conjunto de chaves do Cloud KMS.

  • WRAPPED_KEYSET_ENCODED: um conjunto de chaves encapsulado codificado como um STRING. Confira um exemplo de saída:

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

    Para converter um conjunto de chaves encapsulado codificado em um conjunto de chaves encapsulado decodificado, consulte Decodificar um conjunto de chaves do Cloud KMS.

Gerenciamento de chaves

As seções a seguir contêm tarefas comuns que podem ser realizadas com chaves do Cloud KMS.

Criar um conjunto de chaves

É possível criar conjuntos de chaves encapsulados ou brutos. Para isso, conclua as etapas nas seções a seguir.

Crie um conjunto de chaves bruto.

Execute a consulta a seguir 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

Criar um conjunto de chaves encapsulado

Execute a consulta a seguir para criar um conjunto de chaves encapsulado 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')

Decodificar um conjunto de chaves

Embora as funções SQL que retornam conjuntos de chaves produzam os conjuntos de chaves no formato BYTES, o resultado exibido pelo usuário é codificado e exibido no formato STRING. Se você quiser converter essa string codificada em uma sequência de bytes decodificados que pode ser usada como funções de criptografia de chaves literais, use a consulta a seguir.

Decodificar um conjunto de chaves encapsulado

Execute a consulta a seguir para decodificar um conjunto de chaves encapsulado do Cloud KMS.

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

Decodificar um conjunto de chaves bruto

Execute a consulta a seguir para decodificar um conjunto de chaves bruto.

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

Encapsular um conjunto de chaves encapsulado

Execute a consulta a seguir para reencapsular um conjunto de chaves encapsulado do Cloud KMS com uma nova chave do Cloud KMS. KMS_KEY_CURRENT representa o novo KMS_KEY usado para criptografar o conjunto de chaves. KMS_KEY_NEW representa o novo KMS_KEY usado para criptografar o conjunto de chaves.

SELECT KEYS.REWRAP_KEYSET(
  KMS_KEY_CURRENT,
  KMS_KEY_NEW,
  WRAPPED_KEYSET_DECODED)

Rotacionar um conjunto de chaves encapsulado.

Execute a consulta a seguir para alternar um conjunto de chaves encapsulado 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')

Gerar um conjunto de chaves brutos a partir de um conjunto de chaves encapsulado

Algumas funções de criptografia exigem um conjunto de chaves bruto. Para descriptografar um conjunto de chaves encapsulado do Cloud KMS para produzir um conjunto de chaves bruto, conclua as etapas a seguir.

  1. Crie um conjunto de chaves encapsulado.

  2. Na ferramenta de linha de comando bq, insira os comandos a seguir para salvar um conjunto de chaves encapsulado em um arquivo chamado keyset_to_unwrap, descriptografar o conjunto de chaves encapsulado e produzir a saída 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 ' ' '\'

Gerar um conjunto de chaves encapsulado de um conjunto de chaves bruto

Algumas funções de criptografia exigem um conjunto de chaves encapsulado do Cloud KMS. Para criptografar um conjunto de chaves bruto para produzir um conjunto de chaves encapsulado, conclua as etapas a seguir.

  1. Crie um conjunto de chaves bruto.

  2. Na ferramenta de linha de comando bq, insira os comandos a seguir para salvar um conjunto de chaves bruto em um arquivo chamado keyset_to_wrap, criptografar o conjunto de chaves bruto e produzir a saída 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 ' ' '\'

Gerar uma chave encapsulada para uma função DLP

Para as funções de DLP, você precisa de uma chave criptográfica e usá-la para receber uma chave encapsulada.

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

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

    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 é possível receber o literal BYTES da chave encapsulada ou o formato base64 da chave encapsulada.

    • Bytes literais

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

      A saída será assim:

      \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
      

      A saída será assim:

      CiQA1W20a6Y5elj6xUMn4u4xPwwYVmchVmgKHhCCjSS3yNkMTpsSOQDz5Jg3vAfguw6KaZY0gP/Dh0NnKrcd6ARn9am5WzKppmp/DwW4JGGJTt8jHbNS4EjbtpD/p4SNmw==
      

Ver o número de chaves em um conjunto de chaves

Execute a consulta a seguir para conferir o número de chaves em um conjunto de chaves bruto.

  1. Se você estiver trabalhando com um conjunto de chaves encapsulado, primeiro gere um conjunto de chaves bruto.

  2. Execute esta consulta com o conjunto de chaves bruto:

    SELECT KEYS.KEYSET_LENGTH(KEYSET_DECODED) as key_count;

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

Execute a consulta a seguir para acessar uma representação JSON de um conjunto de chaves bruto.

  1. Se você estiver trabalhando com um conjunto de chaves encapsulado, primeiro gere um conjunto de chaves bruto.

  2. Execute esta consulta com o conjunto de chaves bruto:

    SELECT KEYS.KEYSET_TO_JSON(KEYSET_DECODED);

Criptografia e descriptografia

É possível usar conjuntos de chaves brutos ou encapsulados para criptografar uma coluna em uma tabela. Também é possível usar a criptografia determinística ou não determinística nas colunas. Os exemplos nesta seção usam conjuntos de chaves encapsulados, mas você pode substituí-los por conjuntos de chaves brutos.

Criptografar uma coluna de maneira determinística com um conjunto de chaves encapsulado

Execute a consulta a seguir para criar uma tabela e armazenar um conjunto de chaves encapsulado do Cloud KMS com criptografia determinística em uma coluna chamada encrypted_content.

  1. Crie um conjunto de chaves encapsulado.

  2. Criptografe uma coluna com o conjunto de chaves encapsulado.

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

Descriptografar uma coluna de maneira determinística com um conjunto de chaves encapsulado

Execute a consulta a seguir para descriptografar, de maneira determinística, uma coluna que tenha conteúdo criptografado usando um conjunto de chaves encapsulado do Cloud KMS. Essa consulta pressupõe que você esteja referenciando uma tabela com uma coluna chamada encrypted_content.

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

Criptografar uma coluna sem determinismo com um conjunto de chaves encapsulado

Consulte Criptografar de forma determinista uma coluna com um conjunto de chaves encapsulado, mas substitua DETERMINISTIC_ENCRYPT por AEAD.ENCRYPT. Verifique se o conjunto de chaves é do tipo AEAD_AES_GCM_256.

Descriptografar de forma não determinada de uma coluna com um conjunto de chaves encapsulado

Consulte Descriptografar de maneira determinística uma coluna por um conjunto de chaves encapsulado, mas substitua DETERMINISTIC_DECRYPT_STRING por AEAD.DECRYPT_STRING. Verifique se o conjunto de chaves é do tipo AEAD_AES_GCM_256.

A seguir

  • Saiba mais sobre o Cloud KMS. Este tópico inclui informações conceituais sobre a criptografia no nível da coluna para o Google Cloud.
  • Saiba mais sobre a criptografia AEAD para o BigQuery. Este tópico inclui informações conceituais sobre a criptografia no nível da coluna especificamente para o BigQuery.
  • Saiba mais sobre as funções de criptografia AEAD para o BigQuery. Este tópico contém todas as funções SQL que podem ser usadas para criptografia no nível da coluna no BigQuery.