Linux で OpenSSL を使用して鍵をラップする

Cloud HSM に鍵をインポートするには、PKCS#11 CKM_RSA_AES_KEY_WRAP メカニズムを使用して鍵をラップする必要があります。このトピックでは、OpenSSL を使用して鍵をラップする方法について説明します。

始める前に

ラッピング鍵をまだ持っていない場合:

  1. 鍵をインポートするために準備手順を行います。
  2. インポート ジョブを作成します。
  3. インポート ジョブからラッピング鍵を取得し、ローカルにダウンロードします。

OpenSSL v1.1.0 のセットアップ

PKCS#11 CKM_RSA_AES_KEY_WRAP 標準に従い、OpenSSL を使用して鍵のマテリアルをラップするには、OpenSSL の v1.1.0* が必要です。大部分のメカニズムで、これはデフォルトのバージョンではありません。このトピックでは、OpenSSL のメカニズムのデフォルト インストール済み環境に影響を及ぼさずに、OpenSSL v1.1.0 のローカルコピーをインストール、パッチ適用、およびビルドする手順について説明します。

  1. https://www.openssl.org/source/ で最新の v1.1.0 リリースを確認します。最新バージョンが 1.1.0j ではない場合は、次のステップで使用するためにバージョンを書き留めます。

  2. コマンド プロンプトでローカル フォルダを作成し、OpenSSL リリースをダウンロードして、ファイルを解凍します。1.1.0j 以外の 1.1.0 バージョンを使用している場合は、そのバージョンを使用するように curl コマンドと tar コマンドを変更します。

    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. ローカル OpenSSL コピーにカスタムパッチを適用します。このドキュメントが作成された時点では、バージョン 1.1.0j が最新の OpenSSL バージョンであり、これによって EVP_CIPHER_CTX_FLAG_WRAP_ALLOW フラグは有効にならないため、次のパッチで有効にします。別のバージョンを使用している場合は、下のパッチの「1.1.0j」を修正します。

    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. 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
    

    --prefix および --openssldir オプションは、ホーム ディレクトリにカスタムの OpenSSL インストール済み環境を配置するために使用されます。システムのデフォルト OpenSSL バージョンの置き換えや変更はおすすめしません。また、openssl バイナリをビルド ディレクトリからコピーするだけでは不十分です。

  5. 新しい openssl バイナリが正常にインストールされたことを確認します。

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

    ローカル OpenSSL ファイルが正しい場所にある場合は、test コマンドの出力に FAIL は表示されません。

  6. この openssl は、$HOME/local/ssl/lib/ に置かれているライブラリに対して動的にリンクされており、{ld} を直接実行することはできません。環境変数 LD_LIBRARY_PATH を使用して、{ld} をより簡単に処理できます。openssl は複数回実行するため、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. 新しいバージョンを起動します。

    $HOME/local/bin/openssl.sh
    
  8. version コマンドを実行して、v1.1.0 のパッチ適用済みバージョンが有効であることを確認します。

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

探している通常の openssl インストールの他の部分がある場合は、$HOME/local/ssl/ の下で見つけることができます。たとえば、man ページが必要な場合、以下の場所を探します。

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

環境変数のセットアップ

OpenSSL コマンドでは、入力値として複数のファイルパスが必要です。コマンドをより簡単に実行できるように、ファイルパスに対して環境変数を定義します。

  1. openssl.sh のローカルコピーのパスに OpenSSL_V110 を定義します。

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

    OpenSSL をローカルでセットアップしたときに推奨パスを使用しなかった場合、必要に応じて、OpenSSL_V110 に割り当てられる値を変更します。

  2. インポートする鍵のマテリアルをラップするには、特定の形式にしておく必要があります。対称鍵は、拡張子が .bin のファイルに存在している必要があります。TARGET_KEY をバイナリ形式の鍵の絶対パスに定義します。このコマンドと次のコマンドでは、PATH プレースホルダを適切なパスに置き換えます。

         TARGET_KEY="ABSOLUTE_PATH_TO_KEY_TO_BE_IMPORTED.bin"
    
  3. WRAP_PUB_KEY を Cloud HSM から受け取ったラッピング公開鍵の絶対パスに定義します。

    WRAP_PUB_KEY="ABSOLUTE_PATH_TO_WRAPPING_KEY.pem"
    
  4. ラップされた鍵が書き込まれる場所の絶対パスに RSA_AES_WRAPPED_KEY を定義します。

    RSA_AES_WRAPPED_KEY="ABSOLUTE_PATH_TO_WRAPPED_KEY.bin"
    
  5. 鍵のラップ処理中に、複数の中間ファイルが使用されます。中間ファイルを簡単にクリーンアップするために、ファイルパスに環境変数を定義します。中間ファイルのディレクトリの場所として BASE_DIR を定義します。必要であれば、BASE_DIR に別のパスを使用します。

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

    中間ファイルに環境変数を定義します。

    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"
    

鍵のラップ

  1. 32 バイトの長さの一時的なランダム AES 鍵を生成します。

    "${OPENSSL_V110}" rand -out "${TEMP_AES_KEY}" 32
    
  2. CKM_RSA_PKCS_OAEP を使用して、ラッピング公開鍵で一時 AES 鍵をラップします。

    "${OPENSSL_V110}" rsautl -encrypt \
    -pubin -inkey "${WRAP_PUB_KEY}" \
    -in "${TEMP_AES_KEY}" \
    -out "${TEMP_AES_KEY_WRAPPED}" \
    -oaep
    
  3. CKM_AES_KEY_WRAP_PAD を使用して、一時 AES 鍵でターゲット鍵をラップします。

    "${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}"
    

    -iv A65959A6 を使用すると、A65959A6 が、RFC 5649 仕様で要求されている代替初期値として設定されることに注意してください。

  4. 一時 AES 鍵を抹消した後、削除します。

    dd if=/dev/zero bs=32 count=1 of="${TEMP_AES_KEY}"; rm "${TEMP_AES_KEY}"
    
  5. 2 つのラップされた鍵を連結し、ファイルに出力を書き込みます。ラップ解除プロセスでバイナリ blob の分割方法を認識できるように、2 つのラップされた鍵に対して順序が示される必要があります。

    cat "${TEMP_AES_KEY_WRAPPED}" "${TARGET_KEY_WRAPPED}" > "${RSA_AES_WRAPPED_KEY}"
    
  6. 不要になった中間ファイルを削除します。

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

    ラップされた鍵は ${RSA_AES_WRAPPED_KEY} にあります。

これで、ラップされた鍵を使用して鍵をインポートするリクエストを行えるようになります。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Cloud KMS ドキュメント