Я уже просмотрел эти вопросы и ответы на них:
«Указан неверный тип провайдера» 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));
}