Коллеги,
Когда я пытаюсь использовать сертификат X509 с открытым ключом в файле .cer, я получаю следующее исключение:
{"Сертификат 'CN = name' должен иметь закрытый ключ. У процесса должны быть права доступа к закрытому ключу."}
Вот код клиента, который я использую для установки сертификата. Обратите внимание, что это файл.
var cert = new X509Certificate2(@"C:\mycert.cer");
credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
credentials.ClientCertificate.Certificate = cert;
Хост-код:
namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(HelloIndigo.HelloIndigoService),
new Uri("http://localhost:8000/HelloIndigo")))
{
host.Open();
Console.WriteLine("Service is listening...");
Console.WriteLine();
Console.WriteLine("Number of base addresses: {0}", host.BaseAddresses.Count);
foreach (Uri uri in host.BaseAddresses)
{
Console.WriteLine("\t{0}", uri.ToString());
}
Console.WriteLine();
Console.WriteLine("Number of dispatchers (listeners): {0}", host.ChannelDispatchers.Count);
foreach (ChannelDispatcher dispatcher in host.ChannelDispatchers)
{
Console.WriteLine("\t{0}, {1}", dispatcher.Listener.Uri.ToString(), dispatcher.BindingName);
}
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate the host application");
Console.ReadLine();
}
}
}
}
Host App.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="HelloIndigo.HelloIndigoService" behaviorConfiguration="serviceBehavior">
<endpoint contract="HelloIndigo.IHelloIndigoService" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding"/>
<endpoint contract="IMetadataExchange" binding="wsHttpBinding" bindingConfiguration="mexBinding" address="mex"/> <!-- -->
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="mexBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
<binding name="wsHttpBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" trustedStoreLocation="LocalMachine"/>
</clientCertificate>
<serviceCertificate findValue="name" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<diagnostics performanceCounters="ServiceOnly" wmiProviderEnabled="true">
<messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="100000"/>
</diagnostics>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
Единственный способ заставить его работать - это сгенерировать сертификат в pfx с открытым / закрытым ключом и паролем, но я думаю, что не всегда безопасно иметь пароль на клиенте. Есть ли способ использовать только открытый ключ для проверки подлинности клиента по службе?