Encapsular una clave con OpenSSL en Linux

En este tema se explica cómo envolver manualmente una clave antes de importarla en Cloud KMS. Solo tienes que seguir las instrucciones de este tema si no quieres usar la CLI de Google Cloud para envolver automáticamente la clave antes de importarla. Para ver un resumen de las diferencias, consulta el artículo Cómo funciona la importación de claves.

Puedes completar los pasos de este tema en un plazo de entre 5 y 10 minutos, sin incluir los pasos de la sección Antes de empezar.

Antes de empezar

Antes de envolver una clave, debes completar los siguientes requisitos previos.

  1. Crea un conjunto de claves y una clave de destino, y crea una tarea de importación.
  2. Verifica que tu clave esté disponible de forma local y tenga el formato correcto para importarla a Cloud KMS.
  3. Parchear y volver a compilar OpenSSL

Recuperar la clave de envoltorio

En esta sección se explica cómo obtener la clave de envoltorio de la tarea de importación que has creado en la sección Antes de empezar. Se recomienda usar la Google Cloud consola.

Consola

  1. Ve a la página Gestión de claves de la Google Cloud consola.

    Ve a la página Gestión de claves.

  2. Haga clic en el nombre del conjunto de claves que contiene su tarea de importación.

  3. En la parte superior de la página, haga clic en la pestaña Trabajos de importación.

  4. Haz clic en Más . A continuación, en el menú emergente, haz clic en Descargar clave de envoltorio.

CLI de gcloud

Para verificar que el trabajo de importación está activo, ejecuta el comando gcloud kms import-jobs describe:

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

Ejecuta el siguiente comando para guardar la clave pública de la tarea de importación en ${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. Llama al método ImportJob.get.

  2. Obtén la clave pública a través del campo publicKey de la respuesta ImportJob.get. Este valor es del tipo WrappingPublicKey. El campo pem del tipo WrappingPublicKey es la clave pública codificada en formato de correo con privacidad mejorada (PEM).

Para obtener más información sobre el formato codificado en PEM, consulta el estándar RFC 7468, especialmente las secciones Consideraciones generales y Codificación textual de la información de clave pública del asunto.

Configurar variables de entorno

Los comandos de OpenSSL requieren varias rutas de archivo como valores de entrada. Define variables de entorno para las rutas de los archivos para que sea más fácil ejecutar los comandos. Asegúrate de que tienes acceso de escritura a los directorios que definas a continuación.

  1. Asigna a la variable PUB_WRAPPING_KEY la ruta completa de la clave de envoltorio que has descargado de la tarea de importación. La clave de envoltorio termina en .pem.

    PUB_WRAPPING_KEY="WRAPPING_KEY_PATH"
    

  2. Asigna a la variable TARGET_KEY la ruta completa a la clave sin envolver (de destino).

    TARGET_KEY=TARGET_KEY_PATH
    

    Sustituye TARGET_KEY_PATH por la ruta al archivo .bin de las claves simétricas o por la ruta al archivo .der de las claves asimétricas.

  3. Si se usa el envoltorio con RSA-AES, asigna a la variable TEMP_AES_KEY la ruta completa de la clave AES temporal.

    TEMP_AES_KEY=TEMP_AES_KEY_PATH
    

  4. Asigna a la variable WRAPPED_KEY la ruta completa donde quieras guardar la clave de destino envuelta que esté lista para importarse.

    WRAPPED_KEY=WRAPPED_KEY_PATH
    

  5. Verifica que todas las variables de entorno estén configuradas correctamente con los siguientes 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}
    

Cuando las variables se hayan definido correctamente, podrás envolver la clave. Hay dos enfoques, como se describe a continuación: solo con RSA o con RSA-AES.

Encapsular la clave

Encapsular la clave con RSA

En este método, la clave de destino se encapsula en un bloque RSA. Por lo tanto, el tamaño de la clave de destino está limitado. Por ejemplo, no puedes usar este método para envolver otra clave RSA. Los métodos de importación admitidos son rsa-oaep-3072-sha256 y rsa-oaep-4096-sha256.

  • Encapsula la clave de destino con la clave pública de encapsulado mediante el 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
    

Encapsula la clave con RSA-AES

Con este método, la clave de destino se encapsula con una clave AES temporal. A continuación, la clave AES temporal se encapsula con la clave RSA. Estas dos claves encapsuladas se concatenan y se importan. Como la clave de destino se encapsula mediante AES en lugar de RSA, este método se puede usar para encapsular claves grandes. Los métodos de importación admitidos son rsa-oaep-3072-sha1-aes-256, rsa-oaep-4096-sha1-aes-256, rsa-oaep-3072-sha256-aes-256 y rsa-oaep-4096-sha256-aes-256.

  1. Genera una clave AES aleatoria temporal de 32 bytes y guárdala en la ubicación identificada por ${TEMP_AES_KEY}:

    openssl rand -out "${TEMP_AES_KEY}" 32
    

  2. Encapsula la clave AES temporal con la clave pública de encapsulado mediante el algoritmo CKM_RSA_PKCS_OAEP. Si el método de importación es rsa-oaep-3072-sha1-aes-256 o rsa-oaep-4096-sha1-aes-256, usa sha1 para rsa_oaep_md y rsa_mgf1_md. Usa sha256 para rsa-oaep-3072-sha256-aes-256 y 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. Asigna a la variable OpenSSL_V110 la ruta de tu secuencia de comandos openssl.sh. Si has seguido las instrucciones para parchear y volver a compilar OpenSSL exactamente, puedes usar este comando sin modificar el valor de la variable.

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

  4. Envuelve la clave de destino con la clave AES temporal mediante el algoritmo CKM_AES_KEY_WRAP_PAD y añádela al 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}"
    

    La marca -iv A65959A6 asigna A65959A6 como valor inicial alternativo. Esto es obligatorio según la especificación RFC 5649.

Siguientes pasos