Я использую C # / WCF. У меня есть веб-служба, которую должен вызывать клиент. Это определение службы:
<service behaviorConfiguration="WCFInterface.CommonBehavior" name="WCFInterface.Content">
<endpoint address="" binding="ws2007HttpBinding" bindingConfiguration="wsHttpUserName"
contract="ABB.fTunes.WCFInterface.IContent">
<identity>
<dns value="fTunesTestServer" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
А это привязка:
<ws2007HttpBinding>
<binding name="wsHttpUserName">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</ws2007HttpBinding>
Если я правильно понимаю, сообщения, отправляемые с сервера на клиент, зашифрованы с помощью сертификата. В настоящее время я все еще работаю с сертификатами разработчика. Я создал корневой сертификат, список отзыва сертификатов и ключ на сервере.
Я устанавливаю клиент с помощью установщика Windows, и у меня есть настраиваемое действие установки для установки сертификатов.
Следующий код показывает, как сертификаты добавляются в магазин.
Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClientCertificates.MyRoot.cer");
byte[] buffer = new byte[((int)(manifestResourceStream.Length - 1L)) + 1];
manifestResourceStream.Read(buffer, 0, (int)manifestResourceStream.Length);
manifestResourceStream.Close();
var cert = new X509Certificate2(buffer);
var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
/*
// The CRL is also needed, no idea why
manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClientCertificates.MyRoot.crl");
buffer = new byte[((int)(manifestResourceStream.Length - 1L)) + 1];
manifestResourceStream.Read(buffer, 0, (int)manifestResourceStream.Length);
manifestResourceStream.Close();
cert = new X509Certificate2(buffer);
store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
*/
// This is the key
manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClientCertificates.MyTestServer.cer");
buffer = new byte[((int)(manifestResourceStream.Length - 1L)) + 1];
manifestResourceStream.Read(buffer, 0, (int)manifestResourceStream.Length);
manifestResourceStream.Close();
cert = new X509Certificate2(buffer);
store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
Теперь у меня два варианта поведения: установка сертификатов работает, но когда я вызываю веб-службу, я получаю SecurityNegotiationException
. Когда я добавляю список отозванных сертификатов вручную, связь с сервером работает. Когда я пытаюсь сделать это программно (см. Код выше), это не работает. Я получаю исключение «Не удалось найти запрошенный объект».
Я пытался использовать разные магазины, но безуспешно.
У меня два вопроса: а) Зачем мне нужен CRL на клиенте? б) Если нужно, как программно установить? Где моя ошибка выше?
Спасибо за помощь, Кей