В приложении. 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();
}
}