2016-04-26 2 views
3

In meiner Anwendung, ein Zertifikat zur Client-Authentifizierung programmatisch auf die MY -Speichern mit dem folgenden Code hinzugefügt importiert:Was die Auswirkungen des `PersistKeySet`-StorageFlag ist, wenn ein Zertifikat in C#

//certData is a byte[] 
//password is a SecureString 
X509Certificate2 certificate = new X509Certificate2(certData, password, X509KeyStorageFlags.Exportable); 
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
try 
{ 
    store.Open(OpenFlags.ReadWrite); 
    store.Add(certificate); 
} 
finally 
{ 
    store.Close(); 
} 

Mit diesem Code wurde das Zertifikat korrekt in den MY -Store (Fingerabdruck- und Zertifizierungskette auch korrekt) auf allen von mir getesteten Computern importiert.

Aber auf einigen Computern (Windows 7 Professional SP1 und Widnows Server 2008 R2 mit lokalem Benutzerkonto) konnte das Zertifikat anschließend nicht für Client-Authentifizierung verwendet werden ("konnte keine Vertrauensstellung für den sicheren SSL/TLS-Kanal herstellen")). Auf einem Windows 8.1 Enterprise-Computer mit Domänenbenutzerkonto funktionierte die Authentifizierung manchmal, aber nicht immer.

Ich probierte einige Dinge aus, und fand schließlich eine Lösung in X509KeyStorageFlags.PersistKeySet zu den Speicherflags hinzuzufügen. So ist die erste Zeile ist jetzt:

X509Certificate2 certificate = new X509Certificate2(certData, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); 

Mit diesen Flaggen könnte das Zertifikat auf allen Geräten verwendet werden. Obwohl ich bin froh, dass meine Anwendung jetzt in der erwarteten Weise funktioniert, würde ich gerne verstehen warum? Was genau macht das PersistKeySet-Flag und warum hat es Einfluss darauf, wann und von wem das Zertifikat verwendet werden kann?

MSDN war in diesem Fall nicht sehr hilfreich.

+1

Kann mit dem Schlüssel in Verbindung stehen, der in einem temporären Container anstelle eines permanenten Containers installiert wird. Sehen Sie hier für Details: https://support.microsoft.com/en-gb/kb/950090 – momar

Antwort

6

Beim Importieren eines PFX wird das öffentliche Zertifikatelement in den Speicher geladen, und das Material des privaten Schlüssels wird in einen Schlüsselspeicheranbieter verschoben. Das Standardverhalten in .NET besteht darin, das Material des privaten Schlüssels zu löschen, wenn das X509Certificate2-Objekt Disposed ist (oder seine Ressourcen werden über Garbage Collection finalisiert). Das Flag PersistKeySet verhindert, dass diese Bereinigung stattfindet.

Wenn Sie zu einem permanenten Zertifikatspeicher hinzufügen, müssen Sie immer PersistKeySet festlegen. Wenn Sie einen persistenten Speicher nicht hinzufügen, möchten Sie ihn wahrscheinlich nicht setzen.

Wenn Ihr Importprozess langlebig ist, sehen Sie, dass zu einem beliebigen Zeitpunkt nach dem Import neue Zugriffe auf den privaten Schlüssel fehlschlagen. Wenn es kurzlebig ist, hat es wahrscheinlich immer versagt zu arbeiten.

+0

das war hilfreich, danke! hast du eine zuverlässige Quelle für mich? – GuyMontag

+1

https://support.microsoft.com/en-us/kb/950090 beschreibt Fehler bei der Verwendung von PersistKeySet, https://github.com/dotnet/corefx/issues/8186 beschreibt die beiden aktuellen Modi des Imports, um eine vorgeschlagene Kontrast Der dritte und die .NET Core-Implementierung können auf https://github.com/dotnet/corefx (die .NET Framework-Version wird in der VM behandelt, also nicht auf ReferenceSource) gefunden werden. – bartonjs

0

In meinem Verständnis, das PersistKeySet Flag, falls angegeben, bleibt es die privaten Schlüssel des importierten PFX an der gleichen Stelle, von wo Zertifikat auf der Festplatte, das die Quelle des exportierten PFX (userkeyset oder machinekeyset) war. Wenn der PFX von einem Tool (z. B. pvk2pfx.exe) generiert wurde, gibt es keine Quelle, und der Standardwert wird verwendet (userkeyset).

Wenn in diesem Fall der private Schlüssel des Zertifikats, das die Quelle des exportierten PFX war, im Maschinenkeysatz gespeichert wurde, wird der private Schlüssel unter Maschinenkopfsatz importiert, hier: .

Andernfalls wird es bei userkeyset gespeichert, hier: \Users\user\AppData\Roaming\Microsoft\Crypto\RSA\S-1-....

Wenn Sie möchten, dass Ihr Zertifikat unabhängig vom Ursprungsort des PFX im gesamten System verfügbar ist, sollten Sie stattdessen das MachineKeySet verwenden.