Encapsuler une clé à l'aide d'OpenSSL sur Linux

Cette rubrique explique comment encapsuler manuellement une clé avant d'importer la clé dans Cloud KMS. Vous ne devez suivre les instructions de cette rubrique que si vous ne souhaitez pas encapsuler automatiquement la clé à l'aide de la Google Cloud CLI avant de l'importer. Pour obtenir une présentation des différences, consultez Fonctionnement de l'importation de clés.

Vous pouvez suivre la procédure décrite dans cette rubrique en 5 à 10 minutes, sans compter les étapes Avant de commencer.

Avant de commencer

Avant de pouvoir encapsuler une clé, vous devez remplir les conditions préalables suivantes.

  1. Créez une clé et un trousseau de clés de ciblage, puis créez une tâche d'importation.
  2. Vérifiez que votre clé est disponible localement et correctement formatée pour l'importation dans Cloud KMS.
  3. Appliquez un correctif et recompilez OpenSSL

Récupérer la clé d'encapsulation

Cette section explique comment extraire la clé d'encapsulation de la tâche d'importation que vous avez créée dans la section Avant de commencer. Il est recommandé d'utiliser la console Google Cloud.

Console

  1. Accédez à la page Gestion des clés dans la console Google Cloud.

    Accéder à la page "Gestion des clés"

  2. Cliquez sur le nom du trousseau de clés contenant la tâche d'importation.

  3. Cliquez sur l'onglet Tâches d'importation situé en haut de la page.

  4. Dans le menu contextuel, cliquez sur Plus , puis sur Télécharger la clé d'encapsulation.

gcloud CLI

Pour vérifier que la tâche d'importation est active, exécutez la commande gcloud kms import-jobs describe :

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

Exécutez la commande suivante pour enregistrer la clé publique depuis la tâche d'importation dans ${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. Appelez la méthode ImportJob.get.

  2. Récupérez la clé publique via le champ publicKey de la réponse fournie par ImportJob.get. Cette valeur est de type WrappingPublicKey. Le champ pem du type WrappingPublicKey est la clé publique encodée au format PEM (Privacy Advanced Mail).

Pour plus d'informations sur l'encodage au format PEM, consultez la section RFC 7468, en particulier les sections Remarques générales et Encodage textuel des informations de clé publique du sujet.

Configurer des variables d'environnement

Les commandes OpenSSL nécessitent plusieurs chemins de fichiers en tant que valeurs d'entrée. Définissez des variables d'environnement pour les chemins de fichiers afin de faciliter l'exécution des commandes. Assurez-vous d'avoir accès en écriture aux répertoires que vous définissez ci-dessous.

  1. Définissez la variable PUB_WRAPPING_KEY sur le chemin d'accès complet à la clé d'encapsulation que vous avez téléchargée depuis la tâche d'importation. La clé d'encapsulation se termine par .pem.

    PUB_WRAPPING_KEY="WRAPPING_KEY_PATH"
    

  2. Définissez la variable TARGET_KEY sur le chemin d'accès complet à la clé non encapsulée (cible).

    TARGET_KEY=TARGET_KEY_PATH
    

    Remplacez TARGET_KEY_PATH par le chemin d'accès au fichier .bin pour les clés symétriques ou par celui au fichier .der pour les clés asymétriques.

  3. En cas d'encapsulation avec RSA-AES, définissez la variable TEMP_AES_KEY sur le chemin d'accès complet à la clé AES temporaire.

    TEMP_AES_KEY=TEMP_AES_KEY_PATH
    

  4. Définissez la variable WRAPPED_KEY sur le chemin d'accès complet où vous souhaitez enregistrer la clé cible encapsulée prête pour l'importation.

    WRAPPED_KEY=WRAPPED_KEY_PATH
    

  5. Vérifiez que toutes les variables d'environnement sont correctement définies à l'aide des commandes suivantes :

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

Lorsque les variables sont correctement définies, vous êtes prêt à encapsuler la clé. Il existe deux approches, décrites ci-dessous: avec RSA uniquement ou avec RSA-AES.

Encapsuler la clé

Encapsuler la clé avec du RSA

Dans cette approche, la clé cible est encapsulée dans un bloc RSA. La taille de la clé cible est donc limitée. Par exemple, vous ne pouvez pas utiliser cette méthode pour encapsuler une autre clé RSA. Les méthodes d'importation compatibles sont rsa-oaep-3072-sha256 et rsa-oaep-4096-sha256.

  • Encapsulez la clé cible avec la clé publique d'encapsulation à l'aide de l'algorithme 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
    

Encapsuler la clé avec RSA-AES

Dans cette approche, la clé cible est encapsulée avec une clé AES temporaire. La clé AES temporaire est ensuite encapsulée par la clé RSA. Ces deux clés encapsulées sont concaténées et importées. Étant donné que la clé cible est encapsulée à l'aide d'AES plutôt que de RSA, cette approche peut être utilisée pour encapsuler des clés volumineuses. Les méthodes d'importation compatibles sont rsa-oaep-3072-sha1-aes-256, rsa-oaep-4096-sha1-aes-256, rsa-oaep-3072-sha256-aes-256 et rsa-oaep-4096-sha256-aes-256.

  1. Générez une clé AES aléatoire temporaire d'une longueur de 32 octets et enregistrez-la à l'emplacement identifié par ${TEMP_AES_KEY}:

    openssl rand -out "${TEMP_AES_KEY}" 32
    

  2. Encapsulez la clé AES temporaire avec la clé publique d'encapsulation à l'aide de l'algorithme CKM_RSA_PKCS_OAEP. Si la méthode d'importation est rsa-oaep-3072-sha1-aes-256 ou rsa-oaep-4096-sha1-aes-256, utilisez sha1 pour rsa_oaep_md et rsa_mgf1_md. Utilisez sha256 pour rsa-oaep-3072-sha256-aes-256 et 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. Définissez la variable OpenSSL_V110 sur le chemin d'accès de votre script openssl.sh. Si vous avez bien suivi les instructions pour appliquer un correctif et recompiler OpenSSL, vous pouvez utiliser cette commande sans modifier la valeur de la variable.

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

  4. Encapsulez la clé cible avec la clé AES temporaire à l'aide de l'algorithme CKM_AES_KEY_WRAP_PAD et ajoutez-la à 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}"
    

    L'option -iv A65959A6 définit A65959A6 en tant que valeur initiale alternative. Ceci est requis par la spécification RFC 5649.

Étapes suivantes

  • La clé encapsulée enregistrée à l'emplacement WRAPPED_KEY est maintenant prête à être importée. Pour importer la clé, suivez les instructions de la section Importer une clé encapsulée manuellement.