Чтение сертификатов, сбой / зависание сервера - PullRequest
0 голосов
/ 17 апреля 2020

В приложении. net 4.7.2 asp. net мы полагаемся на сертификаты для связи с нашим провайдером входа и работы с файлами в GoogleDrive с использованием. Net SDK. Однако несколько раз каждый рабочий день (большая нагрузка, чем в выходные дни) сайт перестает отвечать на запросы, это длится около 8-10 минут. Создание дампа и его анализ показывает множество потоков, имеющих одинаковую трассировку стека.

Веб-серверы, испытывающие эту проблему, работают Windows Server 2008R2 и Windows Server 2012.

Надеюсь, кто-то может помочь мне разобраться, что вызывает медленное взаимодействие с сертификатами.

Stacktrace # 1 с 289 потоками, использующими одну и ту же трассировку стека

ntdll!ZwCreateFile+a 
rsaenh!CreateSystemDirectory+106 
rsaenh!CreateNestedDirectories+1fd 
rsaenh!GetUserStorageArea+2b5 
rsaenh!ReadContainerInfo+139 
rsaenh!OpenUserKeyGroup+3e 
rsaenh!NTagLogonUser+3fa 
rsaenh!CPAcquireContext+1f6 
cryptsp!CryptAcquireContextA+bef 
cryptsp!CryptAcquireContextW+ce 
advapi32!CryptAcquireContextWStub+11 
clr!CryptoHelper::WszCryptAcquireContext_SO_TOLERANT+78 
clr!COMCryptography::OpenCSP+1d4 
clr!COMCryptography::_OpenCSP+167 
[[HelperMethodFrame_2OBJ] (System.Security.Cryptography.Utils._OpenCSP)] System.Security.Cryptography.Utils._OpenCSP(System.Security.Cryptography.CspParameters, UInt32, System.Security.Cryptography.SafeProvHandleByRef) 
mscorlib_ni!System.Security.Cryptography.Utils.CreateProvHandle(System.Security.Cryptography.CspParameters, Boolean)+52 
mscorlib_ni!System.Security.Cryptography.Utils.GetKeyPairHelper(System.Security.Cryptography.CspAlgorithmType, System.Security.Cryptography.CspParameters, Boolean, Int32, System.Security.Cryptography.SafeProvHandle ByRef, System.Security.Cryptography.SafeKeyHandle ByRef)+5d 
mscorlib_ni!System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()+87 
mscorlib_ni!System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32, System.Security.Cryptography.CspParameters, Boolean)+c7 
System_ni!System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()+e3 
dk.nita.saml20.protocol.Saml20SignonHandler.TransferClient(dk.nita.saml20.config.IDPEndPoint, dk.nita.saml20.Saml20AuthnRequest, System.Web.HttpContext)+324 
dk.nita.saml20.protocol.Saml20SignonHandler.SendRequest(System.Web.HttpContext)+1c7 
dk.nita.saml20.protocol.Saml20AbstractEndpointHandler.ProcessRequest(System.Web.HttpContext)+39

Stacktrace # 2 с 106 потоками, использующими одну и ту же трассировку стека

[[HelperMethodFrame_PROTECTOBJ] (System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob)] System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[], IntPtr, UInt32, Boolean, System.Security.Cryptography.X509Certificates.SafeCertContextHandleByRef) 
mscorlib_ni!System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[], System.Object, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags)+e1 
System_ni!System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[], System.String, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags)+8a 
UvMedia.FileSharing.GoogleDrive.GoogleDriveServiceFactory.CreateAppsService(UvMedia.FileSharing.ProviderUser, UvMedia.FileSharing.GoogleDrive.GoogleAppsCustomerSettings, UvMedia.FileSharing.GoogleDrive.IGoogleAppsEmailMapper, UvMedia.FileSharing.Logging.ClientInfo, System.Func`1)+db 
UvMedia.FileSharing.GoogleDrive.GoogleDriveFileSharingService..ctor(UvMedia.FileSharing.GoogleDrive.GoogleAppsCustomerSettings, UvMedia.FileSharing.ProviderUser, System.String, System.String, Google.Apis.Drive.v3.DriveService, UvMedia.FileSharing.GoogleDrive.IGoogleAppsEmailMapper)+106 
UvMedia.FileSharing.GoogleDrive.GoogleDriveFileSharingService+d__17.MoveNext()+18e 

Вот код, который загружает сертификат в примере №1. В возвращаемом объекте X509Certificate2 используется только PrivateKey, однако объект X509Certificate2 никогда не располагается в коде, который вызывает GetCertificate ()

public X509Certificate2 GetCertificate()
        {            
            var store = new X509Store( storeName, storeLocation);
            try
            {
                store.Open(OpenFlags.ReadOnly);
                var found = store.Certificates.Find(x509FindType, findValue, validOnly);
                if (found.Count == 0)
                {
                    var msg = $"A configured certificate could not be found in the certificate store. {SearchDescriptor()}";
                    throw new ConfigurationErrorsException(msg);
                }
                if (found.Count > 1)
                {
                    var msg = $"Found more than one certificate in the certificate store. Make sure you don't have duplicate certificates installed. {SearchDescriptor()}";
                    throw new ConfigurationErrorsException(msg);
                }
                return found[0];
            }
            finally
            {
                store.Close();
            }
        }
...