Signieren von MSIX und CI/CD-Pipelines mit Azure Key Vault

Das Signieren ist eine der wichtigen Aufgaben bei der Arbeit mit MSIX-Paketen. Wenn ein MSIX-Paket nicht mit einem vertrauenswürdigen Zertifikat signiert ist, können Benutzer die Anwendung nicht installieren. Zugleich ist das Signieren auch eine der kritischsten Aufgaben im Hinblick auf Sicherheit. Zertifikate müssen sicher gespeichert werden, um zu verhindern, dass böswillig Handelnde sie wiederverwenden können, um ihre Anwendungen mit Ihrer Identität zu signieren. Azure Key Vault ist die beste Option zur Unterstützung dieser Anforderung.

In diesem Artikel erfahren Sie, wie Sie Azure Key Vault in einer CI/CD-Pipeline nutzen können, damit wir das MSIX-Paket automatisch als Teil des Vorgangs signieren können.

Wichtig

Der in diesem Artikel beschriebene Vorgang basiert auf einem Open Source-Tool namens Azure SignTool, das sowohl mit Azure Pipelines als auch mit GitHub Actions funktioniert. Wenn Sie Azure Pipelines verwenden, können Sie auch die MSIX-Erweiterungen in Kombination mit der Azure Key Vault-Aufgabenutzen.

Voraussetzungen

  • Ein Azure-Konto. Wenn Sie noch nicht über ein Azure-Konto verfügen, starten Sie hier.
  • Ein Azure Key Vault. Weitere Informationen finden Sie unter Erstellen eines Schlüsseltresors.
  • Ein gültiges Paketsignaturzertifikat, das in Azure Key Vault importiert wurde. Das von Azure Key Vault generierte Standardzertifikat eignet sich nicht zum Signieren von Code. Details zum Erstellen eines Paketsignaturzertifikats finden Sie unter Erstellen eines Paketsignaturzertifikats.
  • Eine CI/CD-Pipeline, die ein MSIX-Paket generiert, das auf Azure Pipelines-oder GitHub Actions gehostet wird. Weitere Informationen finden Sie unter Konfigurieren der CI/CD-Pipeline mit einer YAML-Datei.

Registrieren einer Anwendung in Azure

Zum Signieren des Pakets als Teil der CI/CD-Pipeline verwenden wir ein Tool namens Azure SignTool. Es funktioniert wie das standardmäßige SignTool-Hilfsprogramm, das im Windows 10-SDK enthalten ist, aber statt ein lokales Zertifikat zu verwenden, stellt es eine Verbindung mit Azure Key Vault her, um eines der verfügbaren Zertifikate zu verwenden. Zum Herstellen der Verbindung müssen wir jedoch zuerst eine Anwendung in Azure registrieren, wodurch wir die Anmeldeinformationen erhalten, die wir benötigen, um Azure SignTool die Authentifizierung bei unserem Azure Key Vault-Dienst zu ermöglichen.

Öffnen Sie das Azure-Portal, und wählen Sie unter den verfügbaren Diensten Azure Active Directory aus. Klicken Sie auf App-Registrierungen und dann auf Neue Registrierung, um den Vorgang zu starten. Geben Sie der Anwendung einen Namen (beispielsweise heißt sie in der Abbildung unten SignToolForContoso), und belassen Sie dann die Standardeinstellungen.

Registrieren einer Anwendung in Azure

Der nächste Schritt besteht darin, die Anwendung als einen öffentlichen Client zu behandeln, da wir uns in einem Szenario befinden, in dem ein Umleitungs-URI nicht erforderlich ist. Wechseln Sie zum Abschnitt „Authentifizierung“ , und ändern Sie unter Erweiterte Einstellungen den Schalter Anwendung als öffentlichen Client behandeln in Ja.

Festlegen der erweiterten Einstellungen

Der letzte Schritt besteht darin, einen geheimen Clientschlüssel zu erstellen. Dies ist das Kennwort, das wir für die Authentifizierung über das Azure SignTool benötigen. Wechseln Sie zum Abschnitt Zertifikate und Geheimnisse, und klicken Sie dann auf Neuer geheimer Clientschlüssel. Geben Sie dem Schlüssel einen Namen, wählen Sie ein Ablaufdatum, und drücken Sie dann auf die Schaltfläche Hinzufügen. Sie werden zurück zur Hauptseite umgeleitet, auf der der geheime Schlüssel zusammen mit seinem Wert aufgelistet wird. Achten Sie unbedingt darauf, ihn zu kopieren und an einem sicheren Ort zu speichern. Sie können Sie ihn danach nicht noch einmal abrufen. Sobald Sie die Seite aktualisieren, wird der geheime Schlüssel maskiert, und es gibt keine Möglichkeit, ihn noch einmal offenzulegen. Ihre einzige Option besteht dann darin, einen neuen geheimen Schlüssel zu generieren.

Es gibt eine letzte Information, die Sie zusammen mit dem geheimen Clientschlüssel speichern müssen: den Anwendungsbezeichner. Wechseln Sie zur Startseite der Anwendung zurück (indem Sie auf Übersicht klicken), und suchen Sie im oberen Abschnitt nach dem Wert Anwendungs-ID (Client) :

Anwendungs-ID

Aktivieren des Zugriffs auf Azure Key Vault

Der nächste Schritt besteht darin, die soeben erstellte Azure-Anwendung für den Zugriff auf unseren Azure Key Vault-Dienst zu konfigurieren. Wechseln Sie auf dem Azure-Portal zu der Instanz von Azure Key Vault, die das Zertifikat enthält, das Sie zum Signieren Ihres MSIX-Pakets verwenden möchten. Wechseln Sie zum Abschnitt Zugriffsrichtlinien, und klicken Sie auf Zugriffsrichtlinie hinzufügen. Das Tool unterstützt die Auswahl einer der verfügbaren Vorlagen, um die Berechtigungen zu definieren, die wir erteilen möchten, aber in unserem Szenario ist keine von ihnen die richtige Wahl. Daher müssen wir mithilfe der Dropdownlisten manuell die folgenden Optionen festlegen:

  • Aktivieren Sie unter Schlüsselberechtigungen die Option Signieren.
  • Aktivieren Sie unter Zertifikatberechtigungen die Option Abrufen.

Der letzte wichtige Schritt besteht darin, anzugeben, welche Anwendung Zugriff auf diese Richtlinie erhalten soll. Klicken Sie auf Prinzipal auswählen, und suchen Sie nach der Azure-Anwendung, die Sie im vorherigen Schritt erstellt haben, indem Sie ihren Namen verwenden. Im Beispiel heißt sie SignToolForContoso.

Prinzipal auswählen

Nachdem Sie sie gefunden haben, klicken Sie auf Auswählen. So sollte die Richtlinie aussehen:

Zugriffsrichtlinie hinzufügen

Wenn Sie den Vorgang abgeschlossen haben, klicken Sie auf Hinzufügen, um die Richtlinie zu erstellen.

Verwenden von Azure SignTool zum lokalen Signieren des Pakets

Nachdem die Azure-Konfiguration jetzt abgeschlossen ist, können wir Azure SignTool verwenden, um das Paket zu signieren. In diesem Abschnitt verwenden wir das Tool lokal, um uns mit dem Tool vertraut zu machen. In den nächsten Abschnitten werden wir es als Teil einer CI/CD-Pipeline verwenden.

Das Tool ist als globales .NET-Tool verfügbar. Vergewissern Sie sich, dass Sie das neueste .NET SDK installiert haben, öffnen Sie dann eine Eingabeaufforderung, und starten Sie den folgenden Befehl:

dotnet tool install --global AzureSignTool 

Jetzt können Sie Ihr Paket mithilfe des AzureSignTool-Befehls signieren, der die folgenden Parameter benötigt:

  • kvu ist die URL Ihres Azure Key Vault. Sie finden ihn auf der Hauptseite des-Diensts im Azure-Portal unter „DNS-Name“.
  • kvi ist die Anwendungs-ID der Azure-App, die Sie registriert und sich zuvor notiert haben.
  • kvs ist der geheime Clientschlüssel, den Sie zuvor erstellt und ebenfalls notiert haben.
  • kvc ist der Anzeigename des Zertifikats, das Sie verwenden möchten.
  • tr ist die URL eines Zeitstempelservers. Mithilfe dieser Option können wir eine Funktion unseres Pakets auch nach dem Ablauf des Zertifikats ermöglichen.
  • v ist der Pfad des MSIX-Pakets, das wir signieren möchten.

Dies ist ein Beispielbefehl:

AzureSignTool sign -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

Verwenden von Azure SignTool mit Azure Pipelines

In diesem Abschnitt wird davon ausgegangen, dass Sie bereits über eine CI/CD-Pipeline für eine Windows-Anwendung verfügen, die mit einer YAML-Datei in Azure Pipelines konfiguriert ist, wie hier erläutert.

Zunächst müssen Sie einige Variablen erstellen, um die Informationen zu speichern, die Azure SignTool zum Herstellen der Verbindung mit Azure Key Vault benötigt. Wählen Sie in Azure DevOps Ihre Pipeline aus, und drücken Sie oben auf die Schaltfläche Bearbeiten. Sobald Sie sich im YAML-Editor befinden, klicken Sie auf die Schaltfläche Variablen oben, um den Bereich zu öffnen. Sie müssen anschließend auf die +-Schaltfläche klicken, um die folgenden Variablen hinzuzufügen:

  • AzureKeyVaultName mit dem Anzeigenamen Ihres Schlüsseltresors.
  • AzureKeyVaultUrl mit der URL Ihres Schlüsseltresors.
  • AzureKeyVaultClientId mit der Anwendungs-ID Ihrer Azure-Anwendung.
  • AzureKeyVaultClientSecret mit dem geheimen Clientschlüssel Ihrer Azure-Anwendung.

Vergewissern Sie sich beim Erstellen der einzelnen Variablen, dass Sie die Option Diesen Geheimniswert beibehalten aktiviert haben. Dadurch wird sichergestellt, dass andere Personen, die Zugriff auf die Pipeline haben, ihre Werte nicht sehen können.

Variable hinzufügen

Jetzt können Sie Ihre vorhandene YAML-Pipeline anpassen, indem Sie eine .NET Core-Aufgabe hinzufügen, um Azure SignTool auf dem Agent zu installieren. Dies ist der YAML-Code, den Sie hinzufügen müssen:

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

Der nächste Schritt besteht darin, eine PowerShell-Aufgabe zum Ausführen des Befehls hinzuzufügen, mit dem das Paket signiert wird. Sie müssen diese Aufgabe nur am Ende des Buildprozesses ausführen, nachdem das MSIX-Paket erstellt wurde.

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

Der Befehl ist ähnlich dem Befehl, den wir zum lokalen Signieren des Pakets verwendet haben. Dies sind die einzigen Unterschiede:

  • Anstelle von festen Werten für die verschiedenen Parameter verwenden wir die Variablen, die wir mit der Syntax $(Variable-Name) erstellt haben
  • Der Pfad des MSIX-Pakets verweist auf den Ordner auf dem Agent, in dem das MSIX-Paket am Ende des Builds erstellt wird.

Verwenden von Azure SignTool mit GitHub Actions

In diesem Abschnitt wird davon ausgegangen, dass Sie bereits über eine CI/CD-Pipeline für eine Windows-Anwendung verfügen, die mit einer YAML-Datei in GitHub Actions konfiguriert ist, wie hier erläutert.

Im ersten Schritt müssen wir wie bei Azure Pipeline die Anmeldeinformationen sicher speichern. GitHub verwendet geheime Schlüssel, und diese können in den Einstellungen Ihres Repositorys hinzugefügt werden. Wenn Sie sich in dem GitHub-Repository befinden, in dem Ihre Windows-Anwendung gehostet ist, klicken Sie auf Einstellungen, und wechseln Sie dann zu Secrets (Geheime Schlüssel).

Ähnlich Ihrem Vorgehen für Azure Pipelines müssen Sie auf New secret (Neuer geheimer Schlüssel) klicken, um vier geheime Schlüssel zu erstellen:

  • AzureKeyVaultName mit dem Anzeigenamen Ihres Schlüsseltresors.
  • AzureKeyVaultUrl mit der URL Ihres Schlüsseltresors.
  • AzureKeyVaultClientId mit der Anwendungs-ID Ihrer Azure-Anwendung.
  • AzureKeyVaultClientSecret mit dem geheimen Clientschlüssel Ihrer Azure-Anwendung.

Der Unterschied zu Azure Pipeline besteht darin, dass Geheimnisse implizit ausgeblendet werden, sodass Sie keine Option zu ihrem Schutz aktivieren müssen.

Jetzt können Sie über die Registerkarte Actions Ihres Repositorys Ihren vorhandenen Workflow öffnen und die Aufgaben hinzufügen, die Sie zum Signieren benötigen. Mit der ersten wird AzureSign Tool auf dem Agent installiert:

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

Die zweite signiert das Paket und muss daher ausgeführt werden, nachdem der Visual Studio-Build abgeschlossen und das MSIX-Paket generiert wurde.

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

Bei dieser Aufgabe gibt es einige Unterschiede im Vergleich zu Azure Pipelines. Der erste ist, dass GitHub eine andere Syntax für den Zugriff auf die geheimen Schlüssel verwendet, die ${{ secrets.SECRET_NAME }} lautet. So werden die verschiedenen Parameter mit den Werten gefüllt, die wir zuvor im Abschnitt "Secrets" erstellt haben. Der andere besteht darin, dass Sie einen anderen Ansatz verwenden müssen, um die zu signierenden MSIX-Pakete zu finden. Die Aufgabe verwendet ein PowerShell-Skript, das alle in der Buildausgabe gespeicherten Dateien durchläuft, statt auf ein bestimmtes MSIX-Paket zu verweisen. Wenn die Datei die Erweiterung MSIX trägt, verwendet sie den AzureSignTool-Befehl, um sie zu signieren.

Bereitstellen des Pakets

Ungeachtet der von Ihnen gewählten CI/CD-Plattform verfügen Sie am Ende des Ablaufs über ein MSIX-Paket, das mit Ihrem in Azure Key Vault gespeicherten Zertifikat signiert ist. Jetzt können Sie jede andere verfügbare Aufgabe verwenden, um das Paket mit Ihrem bevorzugten Distributionsverfahren bereitzustellen: dem Microsoft Store, einer Website, Microsoft Intune usw.