Encapsular uma chave através do OpenSSL no Linux

Este tópico mostra como encapsular manualmente uma chave antes de importar a chave para o Cloud KMS. Só tem de seguir as instruções neste tópico se não quiser usar a Google Cloud CLI para encapsular automaticamente a chave antes de a importar. Para uma vista geral das diferenças, consulte o artigo Como funciona a importação de chaves.

Pode concluir os passos neste tópico em 5 a 10 minutos, sem incluir os passos da secção Antes de começar.

Antes de começar

Antes de poder encapsular uma chave, tem de concluir os seguintes pré-requisitos.

  1. Crie um conjunto de chaves e uma chave de destino, e crie uma tarefa de importação.
  2. Verifique se a chave está disponível localmente e formatada corretamente para importação para o Cloud KMS.
  3. Aplique patch e recompila o OpenSSL

Obtenha a chave de encapsulamento

Esta secção mostra como obter a chave de união da tarefa de importação que criou em Antes de começar. Recomendamos que use a Google Cloud consola.

Consola

  1. Aceda à página Gestão de chaves na Google Cloud consola.

    Aceda à página de gestão de chaves

  2. Clique no nome do conjunto de chaves que contém a tarefa de importação.

  3. Clique no separador Tarefas de importação na parte superior da página.

  4. Clique em Mais , e, de seguida, em Transferir chave de união no menu de pop-up.

CLI gcloud

Para verificar se a tarefa de importação está ativa, 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

Execute o seguinte comando para guardar a chave pública da tarefa 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. Obtenha a chave pública através do campo publicKey da resposta ImportJob.get. Este valor é do tipo WrappingPublicKey. O campo pem do tipo WrappingPublicKey é a chave pública codificada no formato de correio otimizado para privacidade (PEM).

Para mais informações sobre o formato codificado em PEM, consulte o RFC 7468, especialmente as secções Considerações gerais e Codificação textual das informações da chave pública do assunto.

Configure variáveis de ambiente

Os comandos OpenSSL requerem vários caminhos de ficheiros como valores de entrada. Defina variáveis de ambiente para os caminhos dos ficheiros para facilitar a execução dos comandos. Certifique-se de que tem acesso de escrita aos diretórios que definir abaixo.

  1. Defina a variável PUB_WRAPPING_KEY para o caminho completo da chave de união que transferiu da tarefa de importação. A chave de encapsulamento termina em .pem.

    PUB_WRAPPING_KEY="WRAPPING_KEY_PATH"
    

  2. Defina a variável TARGET_KEY para o caminho completo da chave não envolvida (de destino).

    TARGET_KEY=TARGET_KEY_PATH
    

    Substitua TARGET_KEY_PATH pelo caminho para o ficheiro .bin para chaves simétricas ou o caminho para o ficheiro .der para chaves assimétricas.

  3. Se usar a união com RSA-AES, defina a variável TEMP_AES_KEY para o caminho completo para a chave AES temporária.

    TEMP_AES_KEY=TEMP_AES_KEY_PATH
    

  4. Defina a variável WRAPPED_KEY para o caminho completo onde quer guardar a chave de destino envolvida pronta para importação.

    WRAPPED_KEY=WRAPPED_KEY_PATH
    

  5. Verifique se todas as variáveis de ambiente estão definidas corretamente através dos 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 estiverem definidas corretamente, pode encapsular a chave. Existem duas abordagens, conforme descrito abaixo: apenas com RSA ou com RSA-AES.

Encapsule a chave

Encapsule a chave com RSA

Nesta abordagem, a chave de destino é envolvida num bloco RSA. Por conseguinte, o tamanho da chave de destino está limitado. Por exemplo, não pode usar este método para encapsular outra chave RSA. Os métodos de importação suportados são rsa-oaep-3072-sha256 e rsa-oaep-4096-sha256.

  • Encapsule a chave de destino com a chave pública de encapsulamento através do 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
    

Encapsule a chave com RSA-AES

Nesta abordagem, a chave de destino é envolvida com uma chave AES temporária. Em seguida, a chave AES temporária é envolvida pela chave RSA. Estas duas chaves envolvidas são concatenadas e importadas. Uma vez que a chave de destino é envolvida com AES em vez de RSA, esta abordagem pode ser usada para envolver chaves grandes. Os métodos de importação suportados 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 com 32 bytes e guarde-a na localização identificada por ${TEMP_AES_KEY}:

    openssl rand -out "${TEMP_AES_KEY}" 32
    

  2. Encapsule a chave AES temporária com a chave pública de encapsulamento através do 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 para o caminho do script openssl.sh. Se seguiu exatamente as instruções para aplicar patches e recompilar o OpenSSL, pode usar este comando sem modificar o valor da variável.

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

  4. Encapsule a chave de destino com a chave AES temporária através do 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}"
    

    O indicador -iv A65959A6 define A65959A6 como o valor inicial alternativo. Isto é obrigatório pela especificação RFC 5649.

O que se segue?