Unión de una clave con OpenSSL en Linux

En este tema, se muestra cómo unir manualmente una clave antes de importarla a Cloud KMS. Solo debes seguir las instrucciones de este tema si no quieres usar Google Cloud CLI para unir automáticamente la clave antes de importarla. Para obtener una descripción general de las diferencias, consulta Cómo funciona la importación de claves.

Puedes completar los pasos en este tema en 5 a 10 minutos, sin incluir los pasos de Antes de comenzar.

Antes de comenzar

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

  1. Crea un llavero de claves y una clave de destino, y crea un trabajo de importación.
  2. Verifica que la clave esté disponible de forma local y tenga el formato correcto para importarla a Cloud KMS.
  3. Aplica un parche y vuelve a compilar OpenSSL.

Recupera la clave de unión

En esta sección, se muestra cómo recuperar la clave de unión del trabajo de importación que creaste en Antes de comenzar. Se recomienda usar la consola de Google Cloud.

Console

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

    Ir a la página Administración de claves

  2. Haz clic en el nombre del llavero de claves que contiene tu trabajo de importación.

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

  4. Haz clic en Más y, luego, en Descargar clave de unión en el menú emergente.

gcloud CLI

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 comando siguiente para guardar la clave pública del trabajo 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. Recupera la clave pública mediante el 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 con codificación PEM, consulta RFC 7468, en especial, las secciones Consideraciones generales y Codificación textual de la información sobre la clave pública del sujeto.

Configura variables de entorno

Los comandos de OpenSSL requieren varias rutas de acceso a archivos como valores de entrada. Define variables de entorno para las rutas de acceso a archivos a fin de facilitar la ejecución de los comandos. Asegúrate de tener acceso de escritura a los directorios que definas a continuación.

  1. Establece la variable PUB_WRAPPING_KEY en la ruta de acceso completa a la clave de unión que descargaste del trabajo de importación. La clave de unión termina en .pem.

    PUB_WRAPPING_KEY="WRAPPING_KEY_PATH"
    

  2. Establece la variable TARGET_KEY en la ruta de acceso completa a la clave separada (objetivo).

    TARGET_KEY=TARGET_KEY_PATH
    

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

  3. Si unes con RSA-AES, establece la variable TEMP_AES_KEY en la ruta completa a la clave AES temporal.

    TEMP_AES_KEY=TEMP_AES_KEY_PATH
    

  4. Establece la variable WRAPPED_KEY en la ruta de acceso completa en la que deseas guardar la clave de destino unida que está lista para importar.

    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 estén configuradas correctamente, ya puedes unir la clave. Existen dos enfoques, como se describe a continuación: con solo RSA o con RSA-AES.

Une la clave

Une la clave con RSA

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

  • Une la clave de destino con la clave pública de unión con 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
    

Une la clave con RSA-AES

En este enfoque, la clave de destino se une con una clave AES temporal. Luego, la clave RSA une la clave AES temporal. Estas dos claves unidas se concatenan y se importan. Debido a que la clave de destino se une con AES en lugar de RSA, este enfoque se puede usar para unir 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 temporal aleatoria con una longitud de 32 bytes y guárdala en la ubicación que identifica ${TEMP_AES_KEY}:

    openssl rand -out "${TEMP_AES_KEY}" 32
    

  2. Une la clave AES temporal con la clave pública de unión con 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. Configura la variable OpenSSL_V110 como la ruta de tu secuencia de comandos openssl.sh. Si seguiste las instrucciones para aplicar parches y volver a compilar OpenSSL de forma exacta, puedes usar este comando sin modificar el valor de la variable.

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

  4. Une la clave de destino con la clave AES temporal mediante el algoritmo CKM_AES_KEY_WRAP_PAD y adjúntalo a 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 establece A65959A6 como el valor inicial alternativo. Esto es obligatorio según la especificación RFC 5649.

¿Qué sigue?