在 Linux 中使用 OpenSSL 包裝金鑰

本主題說明如何手動包裝金鑰,然後將金鑰匯入 Cloud KMS。只有在您不想使用 Google Cloud CLI 自動包裝金鑰,再匯入金鑰時,才需要按照本主題中的操作說明進行。如要瞭解差異,請參閱「鍵盤匯入功能的運作方式」。

您可以在 5 到 10 分鐘內完成本主題中的步驟,不包括「事前準備」步驟。

事前準備

您必須先完成下列先決條件,才能包裝金鑰。

  1. 建立目標金鑰環和金鑰,並建立匯入工作
  2. 確認金鑰在本機上可用且格式正確,以便匯入至 Cloud KMS。
  3. 修補並重新編譯 OpenSSL

擷取包裝金鑰

本節說明如何從「開始前」建立的匯入工作中擷取包裝金鑰。建議使用 Cloud de Confiance 控制台。

控制台

  1. 前往 Cloud de Confiance 控制台的「Key Management」頁面。

    前往「Key Management」(金鑰管理) 頁面

  2. 按一下包含匯入工作的金鑰環名稱。

  3. 按一下頁面頂端的 [Import Jobs] (匯入工作) 分頁標籤。

  4. 依序按一下「更多」圖示 ,然後點選彈出式選單中的「Download wrapping key」

gcloud CLI

如要確認匯入工作是否處於作用中狀態,請執行 gcloud kms import-jobs describe 指令:

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

執行下列指令,將匯入工作中的公開金鑰儲存至 ${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. 呼叫 ImportJob.get 方法。

  2. 透過 ImportJob.get 回應的 publicKey 欄位擷取公開金鑰。這個值的類型為 WrappingPublicKeyWrappingPublicKey 類型的 pem 欄位是採用隱私強化郵件 (PEM) 格式來編碼的公開金鑰。

如要進一步瞭解 PEM 編碼格式,請參閱 RFC 7468,特別是「一般注意事項」和「主體公開金鑰資訊的文字編碼」章節。

設定環境變數

OpenSSL 指令需要多個檔案路徑做為輸入值。請為這些檔案路徑定義環境變數,以便讓您能更輕鬆地執行指令。請確認您有權寫入下方定義的目錄。

  1. PUB_WRAPPING_KEY 變數設為從匯入工作下載的包裝金鑰的完整路徑。包裝金鑰會在 .pem 結束。

    PUB_WRAPPING_KEY="WRAPPING_KEY_PATH"
    

  2. TARGET_KEY 變數設為未包裝 (目標) 金鑰的完整路徑。

    TARGET_KEY=TARGET_KEY_PATH
    

    TARGET_KEY_PATH 替換為對稱金鑰的 .bin 檔案路徑,或非對稱金鑰的 .der 檔案路徑。

  3. 如果使用 RSA-AES 進行包裝,請將 TEMP_AES_KEY 變數設為臨時 AES 金鑰的完整路徑。

    TEMP_AES_KEY=TEMP_AES_KEY_PATH
    

  4. WRAPPED_KEY 變數設為要儲存已包裝的目標金鑰 (可供匯入) 的完整路徑。

    WRAPPED_KEY=WRAPPED_KEY_PATH
    

  5. 使用下列指令,確認所有環境變數都已正確設定:

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

變數設定正確後,您就可以包裝鍵。有兩種方法,如下所述:使用 RSA 專屬RSA-AES

包裝金鑰

使用 RSA 包裝金鑰

在這種方法中,目標金鑰會在 RSA 區塊中包裝。因此,目標鍵大小受到限制。舉例來說,您無法使用這個方法包裝其他 RSA 金鑰。支援的匯入方法為 rsa-oaep-3072-sha256rsa-oaep-4096-sha256

  • 使用 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
    

使用 RSA-AES 包裝金鑰

在這種方法中,目標金鑰會使用臨時 AES 金鑰包裝。然後,臨時 AES 金鑰會由 RSA 金鑰包裝。這兩個已包裝的金鑰會串連並匯入。由於目標金鑰是使用 AES 而非 RSA 包裝,因此可使用這種方法包裝大型金鑰。支援的匯入方法為 rsa-oaep-3072-sha1-aes-256rsa-oaep-4096-sha1-aes-256rsa-oaep-3072-sha256-aes-256rsa-oaep-4096-sha256-aes-256

  1. 產生長度為 32 個位元組的臨時隨機 AES 金鑰,並將其儲存至 ${TEMP_AES_KEY} 指定的位置:

    openssl rand -out "${TEMP_AES_KEY}" 32
    

  2. 使用 CKM_RSA_PKCS_OAEP 演算法,將臨時 AES 金鑰與包裝公開金鑰包裝在一起。如果匯入方法為 rsa-oaep-3072-sha1-aes-256rsa-oaep-4096-sha1-aes-256,請為 rsa_oaep_mdrsa_mgf1_md 使用 sha1。請為 rsa-oaep-3072-sha256-aes-256rsa-oaep-4096-sha256-aes-256 使用 sha256

    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. OpenSSL_V110 變數設為 openssl.sh 指令碼的路徑。如果您確實按照修補及重新編譯 OpenSSL 的操作說明進行,就可以使用這個指令,而無須修改變數的值。

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

  4. 使用 CKM_AES_KEY_WRAP_PAD 演算法,將目標金鑰與臨時 AES 金鑰包裝在一起,然後附加至 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}"
    

    -iv A65959A6 標記會將 A65959A6 設為備用初始值。這是 RFC 5649 規格的要求。

後續步驟

  • 儲存在 WRAPPED_KEY 的已包裝金鑰現在可供匯入。如要匯入金鑰,請按照「匯入手動包裝的金鑰」中的操作說明進行。