Como encapsular uma chave usando o OpenSSL no Linux

Neste tópico, mostramos como encapsular uma chave manualmente antes de importá-la para o Cloud KMS. Você só precisa seguir as instruções deste tópico se não quiser usar a Google Cloud CLI para encapsular a chave automaticamente antes de importá-la. Para uma visão geral das diferenças, consulte Como funciona a importação de chaves.

Você pode concluir as etapas deste tópico em 5 a 10 minutos, sem incluir as etapas Antes de começar.

Antes de começar

Antes de envolver uma chave, você precisa concluir os seguintes pré-requisitos:

  1. Crie um keyring e uma chave de segmentação e crie um job de importação.
  2. Verifique se a chave está disponível localmente e formatada corretamente para importação no Cloud KMS.
  3. Corrigir e recompilar o OpenSSL

Recuperar a chave de encapsulamento

Esta seção mostra como recuperar a chave de encapsulamento do job de importação criado em Antes de começar. É recomendável usar o console do Google Cloud.

Console

  1. Acesse a página Gerenciamento de chaves no console do Google Cloud.

    Acessar a página "Gerenciamento de chaves"

  2. Clique no nome do keyring que contém o job de importação.

  3. Clique na guia Jobs de importação na parte superior da página.

  4. Clique em Mais e em Fazer o download da chave de encapsulamento no menu pop-up.

CLI da gcloud

Para verificar se o job de importação está ativo, execute o comando gcloud kms import-jobs describe:

gcloud kms import-jobs describe IMPORT_JOB \
  --location LOCATION \
  --keyring KEY_RING \
  --format="value(state)"
state: ACTIVE

Executar o seguinte comando para salvar a chave pública do job de importação em ${HOME}/wrapping-key.pem

gcloud kms import-jobs describe \
  --location=LOCATION \
  --keyring=KEY_RING \
  --format="value(publicKey.pem)" \
  IMPORT_JOB > ${HOME}/wrapping-key.pem

API

  1. Chame o método ImportJob.get.

  2. Recupere a chave pública por meio do campo publicKey da resposta ImportJob.get. Esse valor é do tipo WrappingPublicKey. O campo pem do tipo WrappingPublicKey é a chave pública codificada no formato Privacy Enhanced Mail (PEM).

Para mais informações sobre o formato codificado PEM, consulte RFC 7468, , especialmente as Considerações gerais e as seções Codificação textual das Informações de chave pública do assunto (página em inglês).

Configurar variáveis de ambiente

Os comandos OpenSSL requerem vários caminhos de arquivo como valores de entrada. Defina variáveis de ambiente aos caminhos de arquivo para facilitar a execução dos comandos. Verifique se você tem acesso para gravar nos diretórios definidos abaixo.

  1. Defina a variável PUB_WRAPPING_KEY como o caminho completo para a chave de encapsulamento do job de importação. A chave de encapsulamento termina em .pem.

    PUB_WRAPPING_KEY="WRAPPING_KEY_PATH"
    

  2. Defina a variável TARGET_KEY como o caminho completo da chave desencapsulada (destino).

    TARGET_KEY=TARGET_KEY_PATH
    

    Substitua TARGET_KEY_PATH pelo caminho do arquivo .bin para chaves simétricas ou pelo caminho do arquivo .der para chaves assimétricas.

  3. Ao fazer o encapsulamento com RSA-AES, defina a variável TEMP_AES_KEY como o caminho completo para a chave AES temporária.

    TEMP_AES_KEY=TEMP_AES_KEY_PATH
    

  4. Defina a variável WRAPPED_KEY como o caminho completo em que você quer salvar a chave de destino encapsulada que está pronta para importação.

    WRAPPED_KEY=WRAPPED_KEY_PATH
    

  5. Verifique se todas as variáveis de ambiente estão definidas corretamente usando os seguintes comandos:

    echo "PUB_WRAPPING_KEY: " ${PUB_WRAPPING_KEY}; \
    echo "TARGET_KEY: " ${TARGET_KEY}; \
    echo "TEMP_AES_KEY: " ${TEMP_AES_KEY}; \
    echo "WRAPPED_KEY: " ${WRAPPED_KEY}
    

Quando as variáveis forem definidas corretamente, você vai poder encapsular a chave. Há duas abordagens, conforme descrito abaixo: somente RSA ou RSA-AES.

Unir a chave

Incorporar a chave com RSA

Nessa abordagem, a chave de destino é encapsulada em um bloco de RSA. Portanto, o tamanho da chave de destino é limitado. Por exemplo, não é possível usar esse método para unir outra chave RSA. Os métodos de importação compatíveis são rsa-oaep-3072-sha256 e rsa-oaep-4096-sha256.

  • Una a chave de destino com a chave pública usando o algoritmo CKM_RSA_PKCS_OAEP:

    openssl pkeyutl \
      -encrypt \
      -pubin \
      -inkey ${PUB_WRAPPING_KEY} \
      -in ${TARGET_KEY} \
      -out ${WRAPPED_KEY} \
      -pkeyopt rsa_padding_mode:oaep \
      -pkeyopt rsa_oaep_md:sha256 \
      -pkeyopt rsa_mgf1_md:sha256
    

Incorporar a chave com RSA-AES

Nessa abordagem, a chave de destino é encapsulada com uma chave AES temporária. Depois, a chave AES temporária é encapsulada pela chave RSA. Essas duas chaves encapsuladas são concatenadas e importadas. Como a chave de destino é encapsulada usando AES em vez de RSA, essa abordagem pode ser usada para unir chaves grandes. Os métodos de importação com suporte são rsa-oaep-3072-sha1-aes-256, rsa-oaep-4096-sha1-aes-256, rsa-oaep-3072-sha256-aes-256 e rsa-oaep-4096-sha256-aes-256.

  1. Gere uma chave AES aleatória temporária de 32 bytes e salve-a no local identificado por ${TEMP_AES_KEY}:

    openssl rand -out "${TEMP_AES_KEY}" 32
    

  2. Encapsule a chave temporária AES com a chave pública encapsulada usando o algoritmo CKM_RSA_PKCS_OAEP. Se o método de importação for rsa-oaep-3072-sha1-aes-256 ou rsa-oaep-4096-sha1-aes-256, use sha1 para rsa_oaep_md e rsa_mgf1_md. Use sha256 para rsa-oaep-3072-sha256-aes-256 e rsa-oaep-4096-sha256-aes-256.

    openssl pkeyutl \
      -encrypt \
      -pubin \
      -inkey ${PUB_WRAPPING_KEY} \
      -in ${TEMP_AES_KEY} \
      -out ${WRAPPED_KEY} \
      -pkeyopt rsa_padding_mode:oaep \
      -pkeyopt rsa_oaep_md:{sha1|sha256} \
      -pkeyopt rsa_mgf1_md:{sha1|sha256}
    

  3. Defina a variável OpenSSL_V110 como o caminho do script openssl.sh. Se você seguiu as instruções para corrigir e recompilar o OpenSSL exatamente, pode usar esse comando sem modificar o valor da variável.

    OPENSSL_V110="${HOME}/local/bin/openssl.sh"
    

  4. Una a chave de destino com a chave AES temporária usando o algoritmo CKM_AES_KEY_WRAP_PAD e anexe-a ao WRAPPED_KEY.

    "${OPENSSL_V110}" enc \
      -id-aes256-wrap-pad \
      -iv A65959A6 \
      -K $( hexdump -v -e '/1 "%02x"' < "${TEMP_AES_KEY}" ) \
      -in "${TARGET_KEY}" >> "${WRAPPED_KEY}"
    

    A sinalização -iv A65959A6 define A65959A6 como o valor inicial alternativo. Isso é exigido pela especificação RFC 5649.

A seguir