Ich habe ein C#, .NET4.5.2 Client/Server-System entwickelt, das TLS/SSL zur Kommunikation verwendet. Die Zertifikate werden aus einer Datei geladen. Ich habe die Zertifikatsdateien mit 'MakeCert' erstellt, um eine .pvk- und .cer-Datei zu erstellen, dann habe ich sie mit dem Dienstprogramm 'pvk2pfx' zu einer .pfx kombiniert.X509Certificate-Konstruktor benötigt> 6 Sekunden, um für einen bestimmten Benutzer ausgeführt zu werden
Um die Zertifikate verwende ich sie mit der Überlastung durch Verwendung des X509Certificate2 Konstruktor laden im Dateipfad und das Passwort als Strings weitergeben müssen:
X509Certificate2(string filePath, string password)
ich im Laufe der Zeit habe bemerkt, dass das Laden von Zertifikaten geworden ist sehr langsam. Ich bin mir nicht sicher, ob es ein "Ereignis" gab, das sie verlangsamt oder langsam gemacht hat, aber es dauert nun bis zu 6 Sekunden, um die PFX-Datei zu laden. Laden der CER-Datei ist kein Problem und dauert ~ 0,1 Sekunden.
Ich habe Windows 8.1 und das Problem ist nur für meine Benutzeranmeldung auf dem Laptop.
Ich schrieb den folgenden Test-App das Problem zu überprüfen:
private const string filePath = @"c:\testcert.pfx";
private const string password = "testpassword";
static void Main(string[] args)
{
var stopwatch = new Stopwatch();
try
{
Console.WriteLine("About to create certificate. Press Enter.");
Console.ReadLine();
stopwatch.Start();
var cert = new X509Certificate(filePath, password);
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
Console.WriteLine("Certificate created. About to reset. Press Enter.");
Console.ReadLine();
cert.Reset();
Console.WriteLine("Certificate reset. Press Enter.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
ich einige Kollegen gebeten, führen Sie das Programm auf ihrem PC. Ich habe auch versucht, innerhalb einer VM zu laufen und dann einen neuen Benutzer auf meinem eigenen Laptop einzurichten. In allen Fällen lief es in ~ 0,1 Sekunden, aber für meine normale Benutzeranmeldung läuft es in> 6 Sekunden.
Zuerst rief ich nicht 'Reset()' auf dem Zertifikat an, also dachte ich, dass es irgendwo ein Problem mit einigen temporären Dateien gab, also benutzte ich procmon, um herauszufinden, was vor sich ging. Ich festgestellt, dass einige temporäre Dateien wurden im folgenden Verzeichnis erstellt werden (obwohl sie wurde aufgeräumt, wenn die Anwendung auch ohne den Anruf verlassen Zurücksetzen()):
C:\Users\<username>\AppData\Roaming\Microsoft\Crypto\RSA\<SID>
Nur um sicherzugehen Ich habe versucht, das Löschen Dateien in diesem Verzeichnis, aber es macht keinen Unterschied.
Mit Procmon kann ich sehen, dass es zwei Lücken in der Datei/Registry-Aktivität während des Ladens des Zertifikats gibt, die in einem System nicht auftreten, wo die Last schnell ist. Die erste ist, nachdem es versucht, "dpapi.dll" zu verwenden. Die zweite ist nach einem Lesen in den folgenden 'C: \ Extend \ $ UsnJrnl: $ J: $ DATA'. DPAPI.dll ist die Schnittstelle für Windows Data Protection. Die letztere Datei ist das USN Journal für NTFS, das Dateiänderungen aufzeichnet. Ich bin kein Experte auf beiden und ich bin mir nicht sicher, ob beides relevant ist!
Ich habe dann versucht, mit API Monitor http://www.rohitab.com/apimonitor Systemaufrufe zu beobachten. Wieder bin ich kein Experte, aber ich schleppte mich durch, um zu sehen, was kurz vor den Pausen passierte. Es gibt eine Menge darin, ich verstehe nicht, dass das relevant sein kann oder nicht, und ich begrüße Kommentare dazu, um mich auf das Problem zu konzentrieren.
Der letzte Anruf vor 2 Sekunden Lücke ist ein Memcpy mit dem Stapel folgenden Aufruf:
# Module Address Offset Location
1 RPCRT4.dll 0x74f6378b 0x2378b I_RpcSendReceive + 0x1bb
2 RPCRT4.dll 0x74f6367b 0x2367b I_RpcSendReceive + 0xab
3 RPCRT4.dll 0x74f594df 0x194df NdrServerInitializeNew + 0x83f
4 RPCRT4.dll 0x74f63619 0x23619 I_RpcSendReceive + 0x49
5 RPCRT4.dll 0x74f6398b 0x2398b NdrSendReceive + 0x2b
Höher die potentiell interessante Linien zu sein scheinen:
# Time of Day Thread Module API Return Value Error Duration
64922 6:38:44.348 AM 1 DPAPI.dll SystemFunction040 (0x00ac5a30, 8, RTL_ENCRYPT_OPTION_SAME_LOGON) STATUS_SUCCESS 0.0000402
64923 6:38:44.349 AM 1 CRYPTBASE.dll RtlInitUnicodeString (0x0090e5a8, "\Device\KsecDD") 0.0000004
64949 6:38:44.349 AM 1 RPCRT4.dll RtlInitUnicodeString (0x0090e0b0, "\RPC Control\protected_storage") 0.0000000
ich es schwierig finden, verfolgen Sie den Callstack, aber ich denke, dass diese letztlich von einer Funktion namens CryptQueryObject kommen.
Ich habe den folgenden Artikel gefunden, der relevant sein kann, aber es ist nicht Windows8.1. Ich habe den Ordner% windir% \ Temp nur für den Fall gelöscht, aber auch nicht geholfen.
https://support.microsoft.com/en-gb/kb/931908
Ich erinnere mich an einen Artikel irgendwo zu finden, dass eine Verzögerung vorgeschlagen etwas sein könnte, von CryptQueryObject mit ActiveDirectory- ruft zu tun, aber ich kann den Link nicht finden.
ich wirklich bin auf der Suche nach:
- Wie mein User-Login beheben, damit es nicht 6 Sekunden dauert ein Zertifikat
- Wie zu laden mein Code, um sicherzustellen, OK ist, damit es nicht passieren wieder oder mit anderen Menschen mit dem System
Vielen Dank für jede Hilfe.