Указан неверный тип провайдера - PullRequest
0 голосов
/ 28 августа 2018

Я уже просмотрел эти вопросы и ответы на них:

«Указан неверный тип провайдера» CryptographicException при попытке загрузить закрытый ключ сертификата

Как создать клиентские сертификаты для локального тестирования двусторонней аутентификации по SSL?

Указан неверный тип провайдера. CryptographicException

И этот блог, на который ссылался второй вопрос.

Я подозреваю, что есть проблема с эмитентом сертификата, но я могу ошибаться.

Введение
Я новичок в аутентификации (вы можете прочитать это как идиот). Текущий проект заключается в обновлении существующего веб-сайта и веб-приложения, написанных в Visual Studio 2013 .Net 4.5.1, до Visual Studio 2017 2017. Net версии 4.6.1, чтобы соответствовать требованиям для нового брокера сообщений.

Окружающая среда
Windows 10
Visual Studio 2017 (15.8.1)
IIS 10
Microsoft SQL Server 2017

Описание проблемы
Веб-сервер, написанный на C #, выдает эту ошибку во время аутентификации

    {"IDX10614: AsymmetricSecurityKey.GetSignatureFormater( 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' ) threw an exception.
Key:
    'System.IdentityModel.Tokens.X509AsymmetricSecurityKey'\nSignatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', check to make sure the     SignatureAlgorithm is supported.\nException:'System.Security.Cryptography.CryptographicException: Invalid provider type specified.
       at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
       at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)\r\n   at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
       at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
       at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
       at System.IdentityModel.Tokens.X509AsymmetricSecurityKey.get_PrivateKey()\r\n   at System.IdentityModel.Tokens.X509AsymmetricSecurityKey.GetSignatureFormatter(String algorithm)
       at System.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(AsymmetricSecurityKey key, String algorithm, Boolean willCreateSignatures)'.
    If you only need to verify signatures the parameter 'willBeUseForSigning' should be false if the private key is not be available."}

Предпринятые шаги
Первоначально не было сертификата для проверки, и это вызвало другую ошибку.
В PowerShell работает от имени администратора

New-SelfSignedCertificate -Subject "CN = XxxxxxxXXCA" -DnsName "localhost" -FriendlyName "XxxxxxxXXCA" -KeyUsage DigitalSignature -KeyUsageProperty ALL -KeyAlgorithm RSA -KeyLength 2048

Запуск MMC

Скопируйте созданный сертификат на Локальный компьютер Personal

Копирование сертификата в доверенные корневые центры сертификации локального компьютера

Копирование сертификата доверенным издателям на локальном компьютере

Запустить сайт в IIS

Запуск веб-сервера в Visual Studio 2017

Используйте Advanced REST Client (ARC) для отправки запроса входа на сервер с клиента.

Просмотрите код проверки подлинности в отладчике Visual Studio 2017 в приведенном ниже коде:

Исключение выдается в операторе возврата.

    public string GenerateToken(string email)
    {

        X509Store store = new X509Store(StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadOnly);
        var certs = store.Certificates;

        X509Certificate2 signingCert =
        certs.Cast<X509Certificate2>().FirstOrDefault(cert => cert.FriendlyName == "XxxxxxxXXCA");
        SigningCredentials signingCredentials = new X509SigningCredentials(signingCert);

        var tokenHandler = new JwtSecurityTokenHandler();
        var now = DateTime.UtcNow;

        var customer = _customerService.GetCustomerByEmail(email); 

        var emailClaim = new Claim(ClaimTypes.Email, customer.Email, ClaimValueTypes.String);
        var userIdClaim = new Claim(ClaimTypes.NameIdentifier, customer.Id.ToString(), ClaimValueTypes.Integer);
        var roleClaim = new Claim(ClaimTypes.Role, "customer", ClaimValueTypes.String);

        var claimsList = new List<Claim> { emailClaim, userIdClaim, roleClaim };

        var tokenDescriptor = new SecurityTokenDescriptor()
        {
            AppliesToAddress = "http://localhost/api",
            SigningCredentials = signingCredentials,
            TokenIssuerName = "http://localhost",
            Lifetime = new Lifetime(now, now.AddDays(30)),
            //Lifetime = new Lifetime(now, now.AddDays(1)),
            Subject = new ClaimsIdentity(claimsList)
        };

        store.Close();
        return tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDescriptor));
    }

1 Ответ

0 голосов
/ 28 августа 2018

New-SelfSignedCertificate Командлет по умолчанию использует поставщик хранилища ключей. Большинство .NET Framework (особенно X509Certificate2) не поддерживают ключи CNG. В результате при создании экземпляра X509Certificate2 из сертификата с закрытым ключом, хранящимся в CNG, свойство доступа get для PrivateKey вызывает исключение:

at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()

Я полагаю, вам не принадлежит код, который вызывает getter на PrivateKey, поэтому вам необходимо заново создать сертификат, явно указав имя устаревшего поставщика в параметре -Provider в вызове командлета New-SelfSignedCertificate. Например, вы можете использовать microsoft enhanced rsa and aes cryptographic provider провайдера в качестве значения параметра.

...