Чтение сертификата закрытого ключа TLS / SSL в вашем коде в Службе приложений Azure

Следуя этой статье Microsoft мы получаем доступ к сертификату закрытого ключа в коде, который был загружен в нашу службу приложений. Мы можем найти сертификат по отпечатку пальца, как указано в статье, и прочитать его, но когда мы пытаемся получить доступ к его значениям ключей с помощью следующего кода, мы получаем ошибку CryptographicException: Keyset не существует .. Ошибка возникает при приведении ключ к RSACryptoServiceProvider.

Это сообщение об ошибке вводит в заблуждение, потому что я знаю, что набор ключей действительно существует. На моей виртуальной машине разработки, отличной от Azure, я могу загрузить файл закрытого ключа, как и любой другой сертификат, в хранилище сертификатов локальных машин и, используя тот же код, прочитать их ключ и его значения. Мне действительно пришлось предоставить доступ к ключу сертификата пользователю (идентификатор пула приложений IIS), под которым работает мой сайт локально. Вы можете сделать это в консоли управления Microsoft (см. Изображение). Поэтому мы предполагаем, что это проблема авторизации.

кто-нибудь еще сталкивался с этим?

Предоставление доступа

        // private key
        if (certificate.HasPrivateKey)
        {
            try
            {
                rsa = certificate.PrivateKey as RSACryptoServiceProvider;
            }
            catch (Exception e)
            {
                var message = $"Certificate key cast to RSACryptoServiceProvider: {e.ToString()} Stacktrace: {e.StackTrace}";
                Error.LogError(message);
                throw new Exception(message);
            }
        }

        if (rsa is null)
        {
            var message = $"Certificate with thumbprint {certificate.Thumbprint} contains no private key.";
            Error.LogError(message);
            throw new Exception(message);
        }

        // signiture
        var cspParam = new CspParameters
        {
            KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
            KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
        };

Трассировка стека: 22488 21:52:18 ОШИБКА Приведение ключа сертификата к RSACryptoServiceProvider: System.Security.Cryptography.CryptographicException: набор ключей не существует

в System.Security.Cryptography.Utils.CreateProvHandle (параметры CspParameters, логическое значение randomKeyContainer) в System.Security.Cryptography.Utils.GetKeyPairHelper (CspAlgorithmType keyType, CspAlgorithmType keyType, CspAlgorithmType, параметры CspAlgorithmandleanandlecrypt, параметры SafeweyShareVeyKey, SafewyroveyKeyKey), параметры безопасного ключа и безопасного ключа, безопасный ключ .Cryptography.RSACryptoServiceProvider.GetKeyPair () в System.Security.Cryptography.RSACryptoServiceProvider..ctor (Int32 dwKeySize, параметры CspParameters, логическое значение useDefaultKeySize) в System.Security.Cryptography.Cryptography. CovidLiveAgentController.GetAccessToken () Stacktrace: в System.Security.Cryptography.Utils.CreateProvHandle (параметры CspParameters, логическое значение randomKeyContainer) в System.Security.Cryptography.ConpeleUtils.GetKeyPairPairPairPerformance, параметры SafewandSpAlPerformance, SafewSpAlPerformance, параметры SafewSpAlPlayCaple, SafewSpAlPySPA SafeKeyHandle и сейф eKeyHandle) в System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair () в System.Security.Cryptography.RSACryptoServiceProvider..ctor (Int32 dwKeySize, параметры CspParameters, логическое значение useDefaultKeySize. BCU.Web.Controllers.CovidLiveAgentController.GetAccessToken ()


person M. Brandel    schedule 13.08.2020    source источник
comment
покажите свой код, в котором вы получаете сертификат из магазина.   -  person Crypt32    schedule 13.08.2020


Ответы (1)


Прежде всего, никогда не прикасайтесь к собственности X509Certificate2.PrivateKey. Он устарел и не должен использоваться, если вы используете .NET Framework 4.6+. Вместо этого вам нужно использовать правильный метод расширения для получения объекта закрытого ключа на основе алгоритма закрытого ключа. Подробнее о том, почему свойство PrivateKey плохо, в моем сообщении в блоге: https://www.pkisolutions.com/accessing-and-using-certificate-private-keys-in-net-framework-net-core/

если ключ хранится в хранилище локального компьютера (вместо текущего пользователя), учетной записи пользователя, под которой выполняется приложение, должны быть предоставлены права на чтение закрытого ключа. В данном случае вам следует загрузить сертификат в хранилище Current User \ Personal вместо Local Machine \ Personal, как указано в упомянутая статья. Это устраняет требование предоставления ключевых разрешений.

person Crypt32    schedule 13.08.2020
comment
Спасибо! Я буду тестировать с различными методами расширения. Также некоторая дополнительная информация - это необычный случай в том смысле, что, см. Обновленную статью Microsoft, этот сертификат .pfx загружается в коллекцию закрытых ключей нашей службы приложений Azure. Таким образом, нет способа выбрать, в какой магазин он находится, или предоставить разрешения отдельным пользователям. - person M. Brandel; 13.08.2020
comment
Даже при использовании методов расширения у нас все еще остается та же проблема. Мы скорректировали нашу подписку Azure и количество экземпляров, что, как ни странно, решает проблему, но только время от времени. Когда мы перезапускаем нашу службу приложений, первая попытка завершается успешно, но затем все последующие вызовы того же кода терпят неудачу. - person M. Brandel; 14.08.2020