使用 Azure 金鑰保存庫 簽署 MSIX 和 CI/CD 管線

簽署是使用 MSIX 套件時要執行的重要工作之一。 如果未使用受信任的憑證簽署 MSIX 套件,使用者將無法安裝應用程式。 同時,簽署也是安全性最重要的工作之一。 憑證必須安全地儲存,以避免惡意執行者可以重複使用這些憑證,以使用我們的身分識別簽署其應用程式。 Azure 金鑰保存庫是支援此需求的最佳選項。

在本文中,我們將瞭解如何在 CI/CD 管線中運用 Azure 金鑰保存庫,以便我們可以在程式中自動簽署 MSIX 套件。

重要

本文所述的程式是以名為Azure SignTool的開放原始碼工具為基礎,其適用于Azure Pipelines和GitHub Actions。 如果您使用 Azure Pipelines,也可以利用MSIX 延伸模組Azure 金鑰保存庫 工作

必要條件

  • Azure 帳戶。 如果您沒有 Azure 帳戶,請從這裡開始。
  • Azure Key Vault。 如需詳細資訊,請參閱建立 Key Vault
  • 已匯入 Azure Key Vault 的有效套件簽署憑證。 Azure Key Vault 產生的預設憑證不適用於程式碼簽署。 如需如何建立套件簽署憑證的詳細資訊,請參閱建立套件簽署的憑證
  • CI/CD 管線,其會產生裝載于 Azure Pipelines 或 GitHub Actions 上的 MSIX 套件。 如需詳細資訊,請參閱 使用 YAML 檔案設定 CI/CD 管線

在 Azure 上註冊應用程式

若要將套件簽署為 CI/CD 管線的一部分,我們將使用名為 Azure SignTool的工具。 它的運作方式就像Windows 10 SDK 中包含的標準 SignTool 公用程式一樣,但不會使用本機憑證,而是連線到 Azure 金鑰保存庫,以使用其中一個可用的憑證。 不過,為了建立連線,我們必須先在 Azure 上註冊應用程式,以提供我們需要的認證,讓 Azure SignTool 能夠對 Azure 金鑰保存庫 服務進行驗證。

開啟 Azure 入口網站,然後在可用的服務中選擇Azure Active Directory。 按一下 [ 應用程式註冊] ,然後選擇 [ 新增註冊 ] 以啟動程式。 例如,將名稱提供給應用程式 (,其為下圖中的 SignToolForContoso) ,然後保留預設設定。

Register an application on Azure

下一個步驟是將應用程式視為公用用戶端,因為我們在不需要重新導向 URI 的情況下。 移至 [ 驗證] 區段 ,然後在 [ 進階設定] 下,將切換 [ 將應用程式視為公用用戶端 ] 變更為 [是]。

Set advanced settings

最後一個步驟是建立用戶端密碼,這是我們需要從 Azure SignTool 進行驗證的密碼。 移至 [ 憑證 & 秘密] 區段,然後按一下 [ 新增用戶端密碼]。 為它命名,選擇到期日,然後按 [ 新增 ] 按鈕。 系統會將您重新導向回主頁面,其中秘密會連同其值一起列出。 請務必複製它,並將它儲存在安全的地方。 您將無法再次擷取它。 一旦您重新整理頁面,秘密就會被遮罩,而且沒有任何方式可以顯示。 您唯一的選項是產生新的秘密。

您需要儲存一個最後一個資訊與用戶端密碼:應用程式識別碼。 返回 按一下 [概觀]) ,然後在上方的區段中尋找[應用程式 (用戶端) 識別碼] 值,以 (應用程式主 (:

Application Id

啟用 Azure 金鑰保存庫的存取權

下一個步驟是設定我們剛才建立的 Azure 應用程式,以存取我們的 Azure 金鑰保存庫服務。 從Azure 入口網站移至 Azure 金鑰保存庫 實例,該實例會保存您要用來簽署 MSIX 套件的憑證。 移至 [ 存取原則 ] 區段,然後按一下 [ 新增存取原則]。 此工具支援選擇其中一個可用的範本來定義我們想要授與的許可權,但在我們的案例中,沒有任何一個範本適合。 因此,我們需要使用下拉式清單手動設定下列選項:

  • [金鑰許可權]下,啟用 [簽署 ] 選項。
  • 在 [ 憑證許可權] 下,啟用 [取得 ] 選項。

最後一個重要步驟是指定要存取此原則的應用程式。 按一下 [ 選取主體 ],並使用其名稱搜尋您在上一個步驟中建立的 Azure 應用程式。 在此範例中,稱為 SignToolForContoso

Select principal

找到它之後,請按 [選取]。 這是原則的外觀。

Add access policy

當您完成此程式時,按一下 [ 新增 ] 以建立原則。

使用 Azure SignTool 在本機簽署套件

現在 Azure 設定已完成,我們可以使用 Azure SignTool 來簽署套件。 在本節中,我們將使用工具在本機熟悉此工具。 在下一節中,我們將使用它作為 CI/CD 管線的一部分。

此工具可作為 .NET 全域工具使用。 請務必 安裝最新的 .NET SDK,然後開啟命令提示字元並啟動下列命令:

dotnet tool install --global AzureSignTool 

現在您可以使用 AzureSignTool 命令簽署套件,這需要下列參數:

  • kvu是 Azure 金鑰保存庫的 URL。 您可以在Azure 入口網站的 [DNS 名稱] 底下,于服務的主頁面中找到它。
  • kvi 是您已註冊且先前已注意到的 Azure 應用程式的應用程式識別碼。
  • kvs 是您先前產生的用戶端密碼,且先前已指出。
  • kvc 是您想要使用的憑證易記名稱。
  • tr 是時間戳記伺服器的 URL。 藉由使用此選項,我們可以讓套件在憑證到期時運作。
  • v 是我們想要簽署之 MSIX 套件的路徑。

這是範例命令:

AzureSignTool sign -kvt "<tenantID>" -kvu "https://contosoexpenses-blog.vault.azure.net/" -kvi "64fae35e-cb84-4b9f-86eb-5170d169316d" -kvs "this-is-the-secret" -kvc "MyCertificate" -tr http://timestamp.digicert.com -v .\MyContosoApp.msix

注意

若要深入瞭解 AzureSignTool,請執行 AzureSignTool sign --help

搭配使用 Azure SignTool 搭配 Azure Pipelines

本節假設您已經有一個 CI/CD 管線,適用于在 Azure Pipelines上以 YAML 檔案設定的Windows應用程式,如這裡所述。

首先,您必須建立一些變數來儲存 Azure SignTool 連線到 Azure 金鑰保存庫所需的資訊。 在 Azure DevOps選取管線,然後按頂端的 [編輯] 按鈕。 一旦您在 YAML 編輯器中,請按一下頂端的 [ 變數 ] 按鈕以開啟面板。 您將按一下 [+] 按鈕以新增下列變數:

  • AzureKeyVaultName,具有保存庫的易記名稱。
  • AzureKeyVaultUrl,具有保存庫的 URL。
  • AzureKeyVaultClientId,具有 Azure 應用程式的應用程式識別碼。
  • AzureKeyVaultClientSecret,具有 Azure 應用程式的用戶端密碼。

當您建立每個變數時,請務必啟用 [保留此值 秘密] 選項。 它可確保有管線存取權的其他人員將無法看到其值。

Add variable

現在您可以新增 .NET Core 工作,在代理程式上安裝 Azure SignTool,以自訂現有的 YAML 管線。 這是要新增的 YAML:

- task: DotNetCoreCLI@2
  displayName: 'Install Azure SignTool'
  inputs:
    command: custom
    custom: tool
    arguments: 'install --global AzureSignTool'

下一個步驟是新增 PowerShell 工作,以執行將簽署套件的命令。 建立 MSIX 套件之後,您只能在建置程式結束時執行這項工作。

- powershell: '& AzureSignTool sign -kvu $(AzureKeyVaultUrl) -kvi $(AzureKeyVaultClientId) -kvs $(AzureKeyVaultClientSecret) -kvc $(AzureKeyVaultName) -tr http://timestamp.digicert.com -v "$(System.DefaultWorkingDirectory)\MyPipeline\MyContosoApp\MyContosoApp.msix"'
  displayName: 'Sign the package'

命令類似于我們用來在本機簽署套件的命令。 唯一的差異如下:

  • 我們使用語法$ (Variable-Name) 建立的變數,而不是針對各種參數使用固定值
  • MSIX 套件的路徑會指向在組建結尾建立 MSIX 套件之代理程式上的資料夾。

搭配使用 Azure SignTool 搭配 GitHub Actions

本節假設您已經有WINDOWS應用程式在 GitHub Actions 上設定 YAML 檔案的 CI/CD 管線,如這裡所述。

如同我們在 Azure Pipeline 上所做的一個步驟,我們需要安全地儲存認證。 GitHub會使用秘密,而且可以在存放庫的設定中新增秘密。 一旦您在裝載Windows應用程式的GitHub存放庫上,請按一下[設定],然後移至 [秘密]。

類似于您Azure Pipelines所做的動作,您將按一下 [新增秘密] 來建立四個秘密:

  • AzureKeyVaultName,具有保存庫的易記名稱。
  • AzureKeyVaultUrl,具有保存庫的 URL。
  • AzureKeyVaultClientId,具有 Azure 應用程式的應用程式識別碼。
  • AzureKeyVaultClientSecret,具有 Azure 應用程式的用戶端密碼。

Azure Pipeline 的差異在於秘密會隱含隱藏,因此您不需要啟用任何保護秘密的選項。

現在,透過存放庫的 [ 動作 ] 索引標籤,您可以開啟現有的工作流程,並新增執行簽署所需的工作。 第一個會在代理程式上安裝 AzureSign 工具:

- name: Install AzureSignTool
  run: dotnet tool install --global AzureSignTool

第二個會簽署套件,因此必須在完成Visual Studio組建並產生 MSIX 套件之後執行。

 - name: Sign package
   run: |
        Get-ChildItem -recurse -Include **.msix | ForEach-Object {
        $msixPath = $_.FullName
        & AzureSignTool sign -kvu "${{ secrets.AzureKeyVaultUrl }}" -kvi "${{ secrets.AzureKeyVaultClientId }}" -kvs "${{ secrets.AzureKeyVaultClientSecret }}" -kvc ${{ secrets.AzureKeyVaultName }} -tr http://timestamp.digicert.com -v $msixPath
        }

相較于我們在Azure Pipelines中使用的工作,這項工作有一些差異。 第一個是GitHub使用不同的語法來存取密碼,也就是 ${{ 秘密。SECRET_NAME }}。 因此,各種參數會填入我們先前在 [秘密] 區段中建立的值。 另一種方法是您必須使用不同的方法來尋找要簽署的 MSIX 套件。 工作不會指向特定的 MSIX 套件,而是使用 PowerShell 腳本,逐一查看儲存在組建輸出中的所有檔案。 如果檔案具有 MSIX 副檔名,則會使用 AzureSignTool 命令來簽署它。

部署套件

無論您選擇的 CI/CD 平臺為何,在流程結束時,您都會使用儲存在 Azure 金鑰保存庫 上的憑證簽署 MSIX 套件。 現在您可以使用任何其他可用的工作,使用您慣用的散發選項來部署套件:Microsoft Store、網站、Microsoft Intune等。