Unión de una clave con OpenSSL en Linux

Antes de que puedas importar una clave a Cloud HSM, es necesario que unas tu clave con el mecanismo PKCS#11 CKM_RSA_AES_KEY_WRAP. En este tema, se proporciona información sobre cómo unir la clave con OpenSSL.

Antes de comenzar

Si aún no tienes una clave de unión:

  1. Completa los pasos de Antes de comenzar para importar una clave.
  2. Crea un trabajo de importación.
  3. Recupera la clave de unión del trabajo de importación y descárgala localmente.

Configura la versión 1.1.0 de OpenSSL

Para unir el material de la clave siguiendo el estándar PKCS#11 CKM_RSA_AES_KEY_WRAP con OpenSSL, se requiere su versión 1.1.0*. Esta no es la versión predeterminada en la mayoría de las máquinas. En este tema, se describen los pasos para instalar una copia local de la versión 1.1.0 de OpenSSL, colocarle parches y compilarla, mientras no interfiera en la instalación predeterminada de OpenSSL en la máquina.

  1. Determina la última versión v1.1.0 en https://www.openssl.org/source/. Si la última versión no es 1.1.0j, toma nota de la versión para usarla en el próximo paso.

  2. En una solicitud de comando, crea carpetas locales, descarga la actualización de OpenSSL y descomprímela. Si estás usando una versión 1.1.0 distinta de 1.1.0j, modifica los comandos curl y tar para usar tu versión.

    mkdir $HOME/build
    mkdir -p $HOME/local/ssl
    cd $HOME/build
    curl -O https://www.openssl.org/source/openssl-1.1.0j.tar.gz
    tar -zxf openssl-1.1.0j.tar.gz
    
  3. Aplica un parche personalizado a la copia de OpenSSL local. Para el momento en que se redactó esta documentación, la versión 1.1.0j era la versión de OpenSSL más reciente y esta no habilita la marca EVP_CIPHER_CTX_FLAG_WRAP_ALLOW, por lo que el siguiente parche sí la habilita. Nuevamente, modifica "1.1.0j" en el parche a continuación si usas una versión diferente.

    cat <<-EOF | patch -d $HOME/build/ -p0
    diff -ur orig/openssl-1.1.0j/apps/enc.c openssl-1.1.0j/apps/enc.c
    --- orig/openssl-1.1.0j/apps/enc.c      2017-11-02 10:29:02.000000000 -0400
    +++ openssl-1.1.0j/apps/enc.c   2017-11-18 14:00:31.106304557 -0500
    @@ -478,6 +478,7 @@
              */
    
             BIO_get_cipher_ctx(benc, &ctx);
    +        EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
    
             if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) {
                 BIO_printf(bio_err, "Error setting cipher %s\n",
    EOF
    
  4. Compila la versión local del binario de openssl.

    cd $HOME/build/openssl-1.1.0j/
    ./config --prefix=$HOME/local --openssldir=$HOME/local/ssl
    make -j$(grep -c ^processor /proc/cpuinfo)
    make test
    make install
    

    Las opciones de --prefix y --openssldir se usan para colocar la instalación personalizada de OpenSSL en tu directorio principal. No se recomienda que reemplaces ni modifiques la versión de OpenSSL predeterminada, ni tampoco es suficiente copiar el binario de openssl fuera del directorio de compilación.

  5. Comprueba que el binario de openssl nuevo se instaló correctamente:

    cd $HOME
    
    test -x local/bin/openssl || echo FAIL
    

    Si los archivos de OpenSSL locales se encuentran en la ubicación correcta, no deberías ver FAIL en el resultado del comando de prueba.

  6. Este objeto openssl está vinculado de forma dinámica con las bibliotecas que residen en $HOME/local/ssl/lib/ y {ld} no podrá ejecutarlo directamente. Puedes ayudar a {ld} con el uso de la variable de entorno LD_LIBRARY_PATH. Como vas a ejecutar openssl varias veces, debes crear una secuencia de comandos llamada openssl.sh.

    cd $HOME/local/bin/
    cat > ./openssl.sh <<-EOF
    #!/bin/bash
    env LD_LIBRARY_PATH=$HOME/local/lib/ $HOME/local/bin/openssl "\$@"
    EOF
    chmod 755 ./openssl.sh
    
  7. Inicia la versión nueva.

    $HOME/local/bin/openssl.sh
    
  8. Ejecuta el comando version para confirmar que la versión con parche de la versión 1.1.0 está activa.

    OpenSSL> version
    OpenSSL 1.1.0j  20 Nov 2018
    OpenSSL> exit
    

Si hay otras partes de la instalación normal de openssl que buscas, puedes encontrarlas en $HOME/local/ssl/. Por ejemplo, si necesitas una página de man:

env MANPATH=$HOME/local/share/man/ man openssl

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.

  1. Define OpenSSL_V110 para la ruta de acceso de tu copia local de openssl.sh.

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

    Si no usaste la ruta de acceso recomendada cuando configuraste OpenSSL de forma local, modifica el valor asignado a OpenSSL_V110 cuando sea necesario.

  2. Es necesario que el material de clave que se importará esté en un formato específico antes de unirlo. La clave simétrica debe existir en un archivo con extensión .bin. Define TARGET_KEY para la ruta de acceso absoluta de la clave con formato binario. Para este comando y los siguientes, reemplaza los marcadores de posición PATH con las rutas de acceso correspondientes.

         TARGET_KEY="ABSOLUTE_PATH_TO_KEY_TO_BE_IMPORTED.bin"
    
  3. Define WRAP_PUB_KEY para la ruta de acceso absoluta de la clave pública de unión que recibiste de Cloud HSM.

    WRAP_PUB_KEY="ABSOLUTE_PATH_TO_WRAPPING_KEY.pem"
    
  4. Define RSA_AES_WRAPPED_KEY para la ruta de acceso absoluta de donde se escribirá la clave unida.

    RSA_AES_WRAPPED_KEY="ABSOLUTE_PATH_TO_WRAPPED_KEY.bin"
    
  5. Durante el proceso de unión de claves, se usan varios archivos intermedios. Para que sea más fácil limpiar los archivos intermedios, define variables de entorno para las rutas de acceso a archivos. Define BASE_DIR como la ubicación del directorio de los archivos intermedios. Si lo prefieres, usa una ruta acceso diferente para BASE_DIR.

    BASE_DIR="/tmp/manual_key_wrap"
    mkdir "$BASE_DIR"
    

    Define variables de entorno para los archivos intermedios.

    TEMP_AES_KEY="${BASE_DIR}/temp_aes_key.bin"
    
    TEMP_AES_KEY_WRAPPED="${BASE_DIR}/temp_aes_key_wrapped.bin"
    
    TARGET_KEY_WRAPPED="${BASE_DIR}/target_key_wrapped.bin"
    

Une la clave

  1. Genera una clave AES temporal aleatoria con una longitud de 32 bytes.

    "${OPENSSL_V110}" rand -out "${TEMP_AES_KEY}" 32
    
  2. Une la clave AES temporal con la clave pública de unión mediante CKM_RSA_PKCS_OAEP.

    "${OPENSSL_V110}" rsautl -encrypt \
    -pubin -inkey "${WRAP_PUB_KEY}" \
    -in "${TEMP_AES_KEY}" \
    -out "${TEMP_AES_KEY_WRAPPED}" \
    -oaep
    
  3. Une la clave de destino con la clave AES temporal mediante CKM_AES_KEY_WRAP_PAD.

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

    Ten en cuenta que el uso de -iv A65959A6 establece A65959A6 como el valor inicial alternativo, tal como lo exige la especificación RFC 5649.

  4. Coloca la clave AES temporal en cero y, luego, bórrala.

    dd if=/dev/zero bs=32 count=1 of="${TEMP_AES_KEY}"; rm "${TEMP_AES_KEY}"
    
  5. Concatena las dos claves unidas y escribe el resultado en un archivo. El orden que se muestra para las dos claves unidas es obligatorio a fin de que el proceso de separación determine cómo separar el binario de BLOB.

    cat "${TEMP_AES_KEY_WRAPPED}" "${TARGET_KEY_WRAPPED}" > "${RSA_AES_WRAPPED_KEY}"
    
  6. Borra los archivos intermedios que ya no son necesarios.

    rm "${TEMP_AES_KEY_WRAPPED}"; rm "${TARGET_KEY_WRAPPED}"
    

    Puedes encontrar tu clave unida en ${RSA_AES_WRAPPED_KEY}.

Ahora puedes usar la clave unida a fin de hacer una solicitud para importar tu clave.

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...