Ошибка «Учетные данные, предоставленные пакету, не были распознаны» при аутентификации как сервера с сертификатом, созданным с использованием BouncyCastle - PullRequest
21 голосов
/ 02 ноября 2011

Я пытаюсь создать сертификат, используя dll BouncyCastle.Crypto, который затем используется для аутентификации SslStream в качестве сервера в процессе службы Windows, который выполняется под учетной записью локальной системы.

Однако, когда я получаю вызов SslStream.AuthenticateAsServer (сертификат), он генерирует исключение Win32 с сообщением об ошибке «Учетные данные, предоставленные для пакета, не были распознаны».

Здесь есть несколько вопросов об этом сообщении об ошибке, но, похоже, ни один из них не описывает и не решает мою конкретную проблему.

В надежде, что кто-то сможет предложить некоторую помощь, я включил код, который я использую для создания и установки сертификата:

// First create a certificate using the BouncyCastle classes
BigInteger serialNumber = BigInteger.ProbablePrime(120, new Random());
AsymmetricCipherKeyPair keyPair = GenerateKeyPair();

X509V1CertificateGenerator generator = new X509V1CertificateGenerator();
generator.SetSerialNumber(serialNumber);
generator.SetIssuerDN(new X509Name("CN=My Issuer"));
generator.SetNotBefore(DateTime.Today);
generator.SetNotAfter(DateTime.Today.AddYears(100));
generator.SetSubjectDN(new X509Name("CN=My Issuer"));
generator.SetPublicKey(keyPair.Public);
generator.SetSignatureAlgorithm("SHA1WITHRSA");

Org.BouncyCastle.X509.X509Certificate cert = generator.Generate(
    keyPair.Private, SecureRandom.GetInstance("SHA1PRNG"));

// Ok, now we have a BouncyCastle certificate, we need to convert it to the 
// System.Security.Cryptography class, by writing it out to disk and reloading
X509Certificate2 dotNetCert;

string tempStorePassword = "Password01"; // In real life I'd use a random password
FileInfo tempStoreFile = new FileInfo(Path.GetTempFileName());

try
{
    Pkcs12Store newStore = new Pkcs12Store();

    X509CertificateEntry entry = new X509CertificateEntry(cert);

    newStore.SetCertificateEntry(Environment.MachineName, entry);

    newStore.SetKeyEntry(
        Environment.MachineName,
        new AsymmetricKeyEntry(keyPair.Private),
        new [] { entry });

    using (FileStream s = tempStoreFile.Create())
    {
        newStore.Save(s, 
            tempStorePassword.ToCharArray(), 
            new SecureRandom(new CryptoApiRandomGenerator()));
    }

    // Reload the certificate from disk
    dotNetCert = new X509Certificate2(tempStoreFile.FullName, tempStorePassword);
}
finally
{
    tempStoreFile.Delete();
}

// Now install it into the required certificate stores
X509Store targetStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
targetStore.Open(OpenFlags.ReadWrite);
targetStore.Add(dotNetCert);
targetStore.Close();

Хорошо, теперь я создал и установил сертификат. Затем я настраиваю свою службу Windows для использования этого сертификата, предоставляя ему отпечаток сформированного сертификата. Затем я использую сертификат следующим образом:

// First load the certificate
X509Certificate2 certificate = null;

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);

foreach (X509Certificate2 certInStore in store.Certificates)
{
    if (certInStore.Thumbprint == "...value not shown...")
    {
        certificate = certInStore;
        break;
    }
}

SslStream sslStream = new SslStream(new NetworkStream(socket, false), false);

// Now this line throws a Win32Exception 
// "The credentials supplied to the package were not recognized"
sslStream.AuthenticateAsServer(certificate);

Кто-нибудь знает, в чем может быть проблема?

У меня не возникает проблемы, если я устанавливаю сертификат, созданный с помощью 'makecert', но он не подходит для производственных сертификатов.

Я также пытался создать отдельный сертификат CA x509v1, а затем сертификат x509v3 для проверки подлинности сервера, но я получаю ту же ошибку, поэтому я удалил ее в примере кода для простоты.

Ответы [ 8 ]

39 голосов
/ 03 ноября 2011

Это конкретное сообщение об ошибке звонит в колокол. Я предполагаю, что либо вы не хранили закрытый ключ с сертификатом, либо служба Windows не имеет доступа к закрытому ключу. Чтобы проверить это, откройте оснастку MMC «Сертификаты»:

  1. Выполнить mmc (например, из меню «Пуск»)
  2. Меню Файл> Добавить / Удалить оснастку
  3. Выберите «Сертификаты» на левой панели и нажмите «Добавить»
  4. Выберите «Учетная запись компьютера» (для LocalMachine), затем нажмите «Далее», а затем закончить

Перейдите к сертификату и дважды щелкните в правой панели. На появившейся вкладке Общие вы должны увидеть маленький значок ключа внизу вместе с текстом «У вас есть закрытый ключ, соответствующий этому сертификату». Если нет, то это проблема. Закрытый ключ не был сохранен.

Если закрытый ключ присутствует , нажмите кнопку ОК, чтобы закрыть это диалоговое окно, а затем щелкните правой кнопкой мыши сертификат в правой панели и выберите во всплывающем меню: «Все задачи»> «Управление личными ключами». , В этом диалоговом окне убедитесь, что учетная запись Windows, под которой работает служба, имеет доступ для чтения к закрытому ключу. Если это не так, вот в чем проблема.

Редактировать: Упс, вы написали, что служба работает как локальная система, поэтому это должен быть отсутствующий закрытый ключ, если это одна из этих двух проблем. В любом случае я оставлю проверку доступа к ключу в своем ответе для всех, кто нажмет эту ссылку и не будет работать как локальная система.

11 голосов
/ 27 ноября 2013

Иногда проблема возникает, когда приложение, пытающееся получить сертификат, не имеет достаточных прав для доступа к сертификату, проблему можно решить, запустив приложение от имени администратора.

6 голосов
/ 04 октября 2012

Нашел это решение в Интернете, но я не могу найти источник, чтобы дать кредит.

Поскольку я столкнулся с проблемой «Учетные данные, предоставленные для пакета, не были распознаны» с AuthenticateAsClient () (для проверки клиента), я хотел бы задокументировать, как я решил эту проблему. Это другой метод с той же конечной целью. Поскольку это может быть полезно для AuthenticateAsServer (), подумал, почему бы и нет.

Здесь я конвертирую сертификат BC в сертификат .NET. Добавьте дополнительный шаг при преобразовании его в .NET X509Certificate2, чтобы сохранить его свойство PrivateKey.

Org.BouncyCastle.X509.X509Certificate bcCert;

X509Certificate dotNetCert = DotNetUtilities.ToX509Certificate(bcCert);
X509Certificate2 dotNetCert2 = new X509Certificate2(dotNetCert);

Проблема обнаружена при добавлении закрытого ключа BouncyCastle в закрытый ключ .NET. Сертификаты X509 преобразуются нормально, но не закрытые ключи. Я преобразовал закрытый ключ BC в RSACryptoServiceProvider, используя предоставленные DotNetUtilities. К сожалению, похоже, что преобразование не завершено. Поэтому я создал еще один RSACryptoServiceProvider, который затем инициализировал. Затем я импортировал закрытый ключ в тот, который создал.

// Apparently, using DotNetUtilities to convert the private key is a little iffy. Have to do some init up front.
RSACryptoServiceProvider tempRcsp = (RSACryptoServiceProvider)DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)ackp.Private);
RSACryptoServiceProvider rcsp = new RSACryptoServiceProvider(new CspParameters(1, "Microsoft Strong Cryptographic Provider", 
            new Guid().ToString(), 
            new CryptoKeySecurity(), null));

rcsp.ImportCspBlob(tempRcsp.ExportCspBlob(true));
dotNetCert2.PrivateKey = rcsp;

После этого мне удалось сохранить объект X509Certificate2 непосредственно в хранилище ключей. Мне не нужен сам файл, поэтому я пропустил этот шаг.

3 голосов
/ 29 июня 2018

У меня та же проблема, перепробовал все из множества постов и поисков Google. Но похоже, что я нашел исправить. Когда я изменил Идентифицировать с ApplicationPoolIdentity на LocalSystem все начинает работать отлично.

Может быть кому-нибудь пригодится.

2 голосов
/ 02 апреля 2017

У меня работает на Windows Server 2012 R2 (.net 4.6.1) - «Все задачи> Управление личными ключами» и настройте доступ для всех (настройка IS_IUSRS была недостаточной)

1 голос
/ 13 ноября 2015

У меня была похожая проблема при вызове службы WCF REST из приложения .NET, где мне нужно прикрепить сертификат клиента;Все, что мне нужно было сделать, - это предоставить доступ к сертификату в хранилище сертификатов [консоль mmc] и, конечно же, «NETWORKSERVICE], мой пул IIS был пулом по умолчанию, что указывает на использование учетной записи пользователя NETWORKService.

ошибка, которую я сделалбыло, я скопировал сертификат из другого хранилища на локальный компьютер -> хранилище персонала, где сертификат был защищен паролем. должен явно импортировать сертификат в требуемом хранилище.

1 голос
/ 21 января 2015

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

Как я, наконец, исправил это, использовал инструмент winhttpcertcfg из Windows Resource Kit, чтобы предоставить разрешение конкретному пользователю, который использовал сертификат.

Синтаксис будет:

"C:\Program Files (x86)\Windows Resource Kits\Tools\winhttpcertcfg" -i cert.p12 -c LOCAL_MACHINE\My -a UserWhoUsesTheCert -p passwordforp12
0 голосов
/ 02 ноября 2011

Я не помню эту ошибку, но созданный вами сертификат недопустим для использования в SSL / TLS, включая:

  • сертификат v1 (не v3);
  • недостающие расширения;
  • неверный CN;
  • ...

Об этом говорят несколько RFC, в том числе RFC5246 на TLS (1.2).

Наконец, создание ваших собственных сертификатов не более подходит , чем использование сертификатов, сделанных makecert (но последний может генерировать минимальный набор для использования для SSL / Сертификат TLS-сервера).

Я настоятельно советую вам купить у известного центра сертификации (CA) сертификат SSL / TLS для производства . Это даст вам рабочий сертификат, признанный большинством браузеров и инструментов.

...