Я использую IdentityServer4 и хочу загрузить сертификат подписи из файла. Например,

var certificate = new X509Certificate2(
        path, 
        password, 
        X509KeyStorageFlags.EphemeralKeySet);

services.AddIdentityServer()
        .AddSigningCredential(certificate)
...
certificate.Dispose();

Приведенный выше код не будет работать, когда я запрашиваю токен у IdentityServer. Но это сработает, если я удалю certificate.Dispose();.

Я также попробовал другой вариант. Я создал RsaSecurityKey из закрытого ключа сертификата и использовал его для добавления учетных данных подписи. И в этом случае утилизация ничего не сломает.

var rsk = new RsaSecurityKey(certificate.GetRSAPrivateKey()))

services.AddIdentityServer()
        .AddSigningCredential(rsk)
...
certificate.Dispose()

Так что мой вопрос более общий. Должен ли я утилизировать X509Certificate2 объект, созданный из существующего сертификата?


Microsoft Документы :

Начиная с .NET Framework 4.6, этот тип реализует интерфейс IDisposable. Когда вы закончили использовать тип, вы должны избавиться от него прямо или косвенно.

3
qwermike 28 Май 2019 в 10:51

2 ответа

Лучший ответ

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

3
Crypt32 28 Май 2019 в 09:20

Рассматривая исходный код .NET Core, X509Certificate2 и его базовый класс X509Certificate используют класс CertificatePal для работы с сертификатом. Класс CertificatePal поддерживает создание объектов класса из различных источников: BLOB-объектов, файлов, хранилищ сертификатов. Он вызывает Windows CryptoAPI, чтобы получить дескриптор сертификата при создании объекта. Поэтому после использования объекта необходимо будет освободить ресурсы, на которые указывает указатель. Хорошей новостью является то, что дескриптор хранится в объекте SafeCertContextHandle , который гарантированно закроет дескриптор после того, как сборщик мусора соберет объект X509Certificate2 и завершит вызов финализаторов объекта. объекты. Насколько я понимаю, нам не нужно вызывать метод Dispose вручную.

3
robbie fan 30 Июл 2019 в 09:39