Como usar chaves de criptografia

Visão geral

Por padrão, o Cloud Storage criptografa todos os dados de objeto usando chaves de criptografia gerenciadas pelo Google e o algoritmo de criptografia AES256. No entanto, também é possível usar um dos dois tipos de chave de criptografia, os que você fornece, chamados de chaves de criptografia fornecidas pelo cliente (CSEK, na sigla em inglês) ou os gerenciados pelo Google Cloud KMS, chamados de chaves de criptografia gerenciadas pelo cliente (CMEK, na sigla em inglês). O Cloud Storage não armazena permanentemente as CSEKs nos servidores do Google ou as gerencia. Leia mais sobre essas opções de criptografia em CMEK e CSEK.

A gsutil aceita CSEKs para interagir com objetos do Cloud Storage usando a API JSON. As chaves são fornecidas por meio do arquivo de configuração .boto, assim:

[GSUtil]
encryption_key = ...
decryption_key1 = ...
decryption_key2 = ...

Cada chave é uma string codificada em Base64 RFC 4648 de 256 bits de dados para uso com o algoritmo de criptografia AES256.

A gsutil também aceita CMEKs para criptografar objetos usando a API JSON. Se sua meta for usar uma CMEK para criptografar todos os objetos recém-gravados em algum intervalo, defina a chave KMS padrão desse intervalo. Consulte gsutil help kms. Como alternativa, é possível especificar a CMEK desejada no arquivo de configuração .boto, mas você só precisa especificar o atributo criptografia_key:

[GSUtil]
encryption_key = projects/PROJECT_ID/locations/LOCATION/keyRings/KEYRING/cryptoKeys/KEYNAME

Ainda que a descriptografia de um objeto criptografado por CSEK exija o fornecimento da CSEK em um dos atributos decryption_key, isso não é necessário para descriptografar objetos criptografados pelo CMEK, porque o nome da CMEK usada para criptografar o objeto é armazenado nos metadados do objeto.

Se você quiser especificar CMEKs por comando sem precisar editar o arquivo boto, especifique o nome da chave como opção boto de nível superior:

gsutil -o 'GSUtil:encryption_key=projects/PROJECT_ID/locations/LOCATION/keyRings/KEYRING/cryptoKeys/KEYNAME' \
       cp /some/local/file gs://my-bucket/

Comportamento da criptografia

Uma única chave de criptografia pode ser especificada no arquivo de configuração .boto, e várias chaves de decodificação podem ser especificadas.

Se encryption_key existir no arquivo de configuração .boto, o gsutil garantirá que os dados gravados ou copiados no Cloud Storage sejam criptografados com essa chave. Se encryption_key não for fornecido, a gsutil garantirá que todos os dados gravados ou copiados usem o tipo de criptografia padrão do bucket de destino. Se o bucket tiver um conjunto de chaves do KMS padrão, esse CMEK será usado para criptografia. Caso contrário, a criptografia gerenciada pelo Google será usada.

Objetos criptografados com CSEKs exigem a chave de descriptografia correspondente sempre que forem baixados ou copiados (por meio dos comandos gsutil cat, cp, mv ou RSync). A visualização dos hashes CRC32C ou MD5 desses objetos (por meio dos comandos ls -L ou stat) também requer a chave de descriptografia correspondente.

Se uma chave correspondente existir na configuração .boto, a gsutil a fornecerá conforme necessário nas solicitações para o Cloud Storage e operará nos resultados descriptografados. A gsutil nunca armazena dados criptografados no disco local.

A gsutil detecta automaticamente a CSEK correta para usar em um objeto de nuvem comparando o hash SHA256 da chave com o hash da CSEK. A gsutil considera a chave de criptografia configurada e até 100 chaves de descriptografia ao pesquisar uma correspondência. As chaves de descriptografia precisam ser listadas no arquivo de configuração boto em ordem numérica crescente, começando com 1. Por exemplo, na configuração a seguir:

decryption_key1 = ...
decryption_key9 = ...
decryption_key10 = ...
decryption_key11 = ...

decryption_keys 9, 10 e 11 serão ignorados porque nenhum valor para decryption_keys 2 a 8 foi fornecido.

Operações recuperáveis e chaves de criptografia

Se a chave de criptografia no seu arquivo de configuração boto for alterada durante uma operação de gravação ou cópia parcialmente concluída (por exemplo, se você executar novamente um upload de objeto gsutil cp após pressionar ^C ou encontrar um tempo limite de rede), A gsutil reiniciará a operação parcialmente concluída para garantir que o objeto de destino seja gravado com a nova chave.

Como gerar chaves de criptografia fornecidas pelo cliente

A geração de uma string codificada em Base64 RFC 4648 para uso como chave de criptografia pode ser feita facilmente com o Python:

python -c 'import base64; import os;\
           print(base64.encodestring(os.urandom(32)))'

Como gerenciar chaves de criptografia fornecidas pelo cliente

Como o Google não armazena CSEKs, se você perder a CSEK, perderá permanentemente o acesso a todos os dados criptografados com essa chave. Portanto, é recomendável fazer backup de cada chave de criptografia em um local seguro. O arquivo de configuração .boto nunca pode ser o único lugar onde sua chave é armazenada.

Além disso, quando você cria uma CSEK, qualquer pessoa que tenha a chave e o acesso aos seus objetos pode ler os dados desses objetos. Tome cuidado para garantir que suas chaves de criptografia não sejam compartilhadas com terceiros não confiáveis.

Como fazer a rotação de chaves

Para alternar as CSEKs, você pode alterar o valor de configuração criptografia_key para um valor de configuração decryption_key e, em seguida, usar um novo valor para a criptografia_key. Em seguida, use o comando de regravação para alternar as chaves na nuvem sem fazer o download e upload dos dados novamente. Por exemplo, se a configuração inicial for:

# Old encryption key
encryption_key = keyA...

Você pode alterá-la para:

# New encryption key
encryption_key = keyB...
# Encryption key prior to rotation
decryption_key1 = keyA...

e gire a chave de criptografia em um objeto executando:

gsutil rewrite -k gs://bucket/object temp-file

Também é possível fazer isso para aplicar diferentes CMEKs, mas não é necessário adicionar CMEKs aos valores de configuração decryption_key. Da mesma maneira, é possível alternar entre a criptografia CSEK e CMEK, dependendo do tipo de chave especificado no valor de configuração encryption_key.

Implicações de desempenho para chaves de criptografia

Ao realizar uma listagem de objetos, os metadados de objetos criptografados com uma CSEK ou CMEK não incluirão os hashes CRC32C ou MD5 dos objetos. Para comandos da gsutil que exigem esses campos, como gsutil ls -L, a gsutil executa uma solicitação GET de metadados adicional para cada objeto criptografado com uma CSEK ou CMEK. Portanto, listar esses objetos com a sinalização -L exigirá uma operação adicional por objeto, que será substancialmente mais lenta do que listar objetos criptografados com chaves de propriedade do Google.

Implicações de segurança para chaves de criptografia fornecidas pelo cliente

A gsutil sempre envia chaves de criptografia por HTTPS para que suas CSEKs nunca fiquem visíveis na rede. No entanto, as chaves estão presentes no arquivo de configuração .boto, bem como na memória da máquina que executa o gsutil. Portanto, se o arquivo ou a máquina estiverem comprometidos, as chaves de criptografia também serão consideradas comprometidas, e você deverá executar a rotação de chaves imediatamente para todos os objetos criptografados com as chaves comprometidas.

API XML não compatível

A gsutil não é compatível com o uso da API XML para interagir com objetos criptografados e usará a API JSON se alguma chave de criptografia ou decryption_key for especificada na configuração.