Freigeben über


HLK-Signatur mit einem HSM

Einführung

Dieser Artikel beschreibt einige der Einrichtungs- und Konfigurationsprobleme, die auftreten können, wenn ein netzwerkbasiertes Hardwaresicherheitsmodul (HSM) verwendet wird, um erweiterte Validierungszertifikate (EV) zu speichern.

Hintergrund

HLK-Paketierung

Für HLKX-Paketdateien gelten die Open Packaging-Konventionen. Die Spezifikation ist Teil einer ISO-Arbeitsgruppe, was bedeutet, dass HLKX-Dateien nicht mit Signtool kompatibel sind.

HLK-Paketsignierung

Wenn das HLK ein Paket signiert, werden die Signaturen und Beziehungen zusammen mit den HLK-Daten im Paket platziert. Dies sind die Daten, die System.IO.Packaging.PackageDigitalSignature zum Überprüfen der Signatur für die Daten im Paket verwendet.

Hinweis

Derzeit unterstützt die HLK-Paketsignierung gemäß der .NET-Bibliothek, die zum Signieren von System.Security.Cryptography.Xml.SignedXml verwendet wird, nur RSA- und DSA-Zertifikate.

Kryptografiedienstanbieter

Ein Kryptografiedienstanbieter (CSP, Cryptography Service Provider) enthält Implementierungen kryptografischer Standards und Algorithmen. Ein CSP besteht mindestens aus einer Dynamic Link Library (DLL), die die Funktionen in CryptoSPI (einer Systemprogrammschnittstelle) implementiert. Die meisten CSPs enthalten die Implementierung aller eigenen Funktionen. Einige CSPs hingegen implementieren ihre Funktionen hauptsächlich in einem Windows-basierten Dienstprogramm, das vom Windows-Dienststeuerungs-Manager verwaltet wird. Andere implementieren Funktionen in Hardware, z. B. einer Smartcard oder einem sicheren Koprozessor. Wenn ein CSP keine eigenen Funktionen implementiert, fungiert die DLL als Passthrough-Schicht für die Kommunikation zwischen dem Betriebssystem und der tatsächlichen CSP-Implementierung.

Zertifikatspeicher und Registrierung

Zertifikate im Zertifikatspeicher sind einer CSP-DLL zugeordnet, die die endgültige Signierung durchführt. Dies ist auf dem folgenden Registrierungseintrag zu sehen.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider]
"Image Path"="%SystemRoot%\\system32\\dssenh.dll"
"SigInFile"=dword:00000000
"Type"=dword:0000000d

HLKX-Paketsignatur mit einem Zertifikat, das von einem netzwerkbasierten HSM gehostet wird

Controller-Konfiguration

Um einen HLK-Controller für die Signierung mit einem HSM-Zertifikat einzurichten, muss folgendes auf dem System vorhanden sein:

  • Eine Zertifizierungsstelle (Zertifizierungsstelle) aus dem HSM
  • Eine CSP-Datei aus dem HSM

Das Vorgehen zum Konfigurieren eines HSM-Clients mit diesen Komponenten sollte von Ihrem HSM-Anbieter dokumentiert sein.

Signieren mit dem HLK

Wenn der Controller ordnungsgemäß konfiguriert ist, sollten Sie so auf das Zertifikat des HSM verweisen können, als wäre es ein lokal installiertes Zertifikat aus dem HLK und das Paket signieren können.

Testen der HSM-Konfiguration

Verwenden von SignTool

Ob Sie signieren können, finden Sie heraus, indem Sie eine Datei mithilfe von SignTool signieren. So sehen Sie, ob der Signaturworkflow ordnungsgemäß funktioniert. Signieren Sie zunächst eine PE-Datei (exe oder dll). Verwenden Sie beispielsweise einen Namen zum Signieren:

signtool sign /f HighValue.cer /csp "Hardware Cryptography Module" /kHighValueContainerMyControl.exe
signtool sign /n "My Company Certificate" MyFile.exe

oder signieren Sie mit dem SHA1-Hash des installierten Zertifikats:

signtool sign /sha1 0cf1d2f7befc7d143678f86963aef5572b710cf2 MyFile.exe

Der Zertifikatname befindet sich in den Betreffinformationen und der SHA1-Hash befindet sich im Fingerabdruck. Wenn Sie den Hash verwenden, entfernen Sie alle Leerzeichen und Sonderzeichen, die sich im Hash befinden, damit das Format dem obigen Beispiel entspricht. Sie können auch mit einer Personal Information Exchange(PFX)-Datei signieren. Dies ist meist nicht empfehlenswert, da eine PFX-Datei den privaten Schlüssel enthalten kann, während ein Zertifikat nur den öffentlichen Schlüssel enthält.

signtool sign /f certdata.pfx MyFile.exe

Sie können die Signatur mithilfe von SignTool verifizieren.

signtool verify /v /pa MyFile.exe

Wenn Sie eine Datei mit allem außer einer PFX-Datei signieren und verifizieren konnten, können Sie versuchen, ein HLK-Paket zu signieren. Wenn das Signieren fehlschlägt, ziehen Sie den Abschnitt „Problembehandlung“ zu Rate.

Verwenden von PackageDigitalSignature

Unter den Codebeispielen Ende dieses Dokuments finden Sie ein Codebeispiel für die Signierung mit PackageDigitalSignature. Sie sollten zusammen mit diesem Dokument auch die vollständige C#-Datei erhalten haben. Um dieses Beispiel zu verwenden, müssen Sie einen vollständigen Pfad zu Ihrem nicht signierten Paket sowie den Fingerabdruck des Zertifikats bereitstellen, das Sie zum Signieren verwenden. Wenn das Signieren fehlschlägt, ziehen Sie den Abschnitt „Problembehandlung“ zu Rate.

Problembehandlung

Die wahrscheinlichste Ursache besteht darin, dass kein Zertifikat und zu Ihrem HSM zugehöriger CSP auf Ihrem System installiert ist. Im Folgenden sind einige der Dinge aufgeführt, die Sie ausprobieren können:

  • Können Sie auf diesem System signieren, wenn Sie nur von Ihrem HSM-Anbieter unterstützte Tools verwenden?
  • Installiert Ihr HSM-Anbieter ein Zertifikat und einen CSP auf diesem System?
    • Was sind die Zertifikateigenschaften?
  • Unterstützt und dokumentiert Ihr HSM-Anbieter die Verwendung von SignTool? Wenn eine Datei mit SignTool mit einem HSM signiert werden kann, spricht das dafür, dass das System ordnungsgemäß konfiguriert wurde und das HLK folglich auch HLKX-Pakete signieren kann.
  • Beim Ausführen des Beispielcodes (HSM_example.cs) wird für die CspKeyContainerInfo.ProviderName ausgegeben.
    • Ist dieser Anbietername der korrekten CSP-DLL zugeordnet? Diese Informationen finden Sie wie oben gezeigt in der Registrierung.

Codebeispiele

PackageDigitalSignatureManager

public static void Sign(string package, X509Certificate2 certificate)
{
  // Open the package to sign it
  Package packageToSign = Package.Open(package);

  // Specify that the digital signature should exist 
  // embedded in the signature part
  PackageDigitalSignatureManager signatureManager = new PackageDigitalSignatureManager(packageToSign);

  signatureManager.CertificateOption = CertificateEmbeddingOption.InCertificatePart;

  // We want to sign every part in the package
  List<Uri> partsToSign = new List<Uri>();
  foreach (PackagePart part in packageToSign.GetParts())
  {
    partsToSign.Add(part.Uri);
  }

  // We will sign every relationship by type
  // This will mean the signature is invalidated if *anything* is modified in                           //the package post-signing
  List<PackageRelationshipSelector> relationshipSelectors = new List<PackageRelationshipSelector>();

  foreach (PackageRelationship relationship in packageToSign.GetRelationships())
  {
    relationshipSelectors.Add(new PackageRelationshipSelector(relationship.SourceUri, PackageRelationshipSelectorType.Type, relationship.RelationshipType));
  }

  try
  {
    signatureManager.Sign(partsToSign, certificate, relationshipSelectors);
  }
  finally
  {
    packageToSign.Close();
  }
}