我开发了一个应用程序,它启动了几个使用SecurityMode.Message加密通信的WCF服务。
它正在运行,但是,它非常复杂,因为我们必须生成SSL证书并将其放在特定的商店,服务器和客户端上。
问题是将使用该程序的客户:
那么我最好的投篮是什么?我只需要加密数据,我不需要确保我连接到正确的主机。
我知道我不是最好的情况,但某些特定用户会使用该应用程序。
这是我的代码的一部分,它建立了连接:
服务器端:
ServiceHost host = new ServiceHost(typeof(MyServiceType))
WSHttpBinding binding = new WSHttpBinding
{
ReaderQuotas = { MaxStringContentLength = int.MaxValue, MaxArrayLength = int.MaxValue, MaxDepth = int.MaxValue, MaxBytesPerRead = int.MaxValue, MaxNameTableCharCount = int.MaxValue },
MaxReceivedMessageSize = int.MaxValue
};
TimeSpan timeoutSpan = TimeSpan.FromMilliseconds(timeout);
binding.CloseTimeout = timeoutSpan;
binding.OpenTimeout = timeoutSpan;
binding.ReceiveTimeout = timeoutSpan;
binding.SendTimeout = timeoutSpan;
binding.ReliableSession.InactivityTimeout = timeoutSpan;
binding.MaxBufferPoolSize = int.MaxValue;
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, ConfigurationManager.AppSettings["Hostname"]);
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
host
.AddServiceEndpoint(services[port], binding, String.Format("http://localhost:{0}", port));
客户端:
string remoteAddress = String.Format("{0}://{1}:{2}", Tools.GetDescription(accessInfo.ServiceHost.Protocol), accessInfo.ServiceHost.HostName, accessInfo.PortNumber);
// avoid seralization/deserialization problems with large XML's
WSHttpBinding binding = new WSHttpBinding();
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.ReaderQuotas.MaxDepth = int.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
TimeSpan timeoutSpan = DateTime.Now.AddMinutes(30) - DateTime.Now;
binding.CloseTimeout = timeoutSpan;
binding.OpenTimeout = timeoutSpan;
binding.ReceiveTimeout = timeoutSpan;
binding.SendTimeout = timeoutSpan;
binding.ReliableSession.InactivityTimeout = timeoutSpan;
binding.MaxBufferPoolSize = int.MaxValue;
//we set the security type
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
ChannelFactory<TService> channelFactory = new ChannelFactory<TService>(binding, remoteAddress);
_service = channelFactory.CreateChannel();
请注意,我删除了有关我的自定义身份验证的部分以获得更干净的代码
答案 0 :(得分:4)
您的客户希望Windows域外的安全性=您的客户需要证书。没有证书=没有安全性。这是您必须向您的客户解释的内容。
您只需要在服务器上拥有带私钥的证书,并且客户端必须信任该证书(如果它信任发布者,则不必安装它)。这是什么意思?您有三种选择:
这就是安全工作的方式。您可以自己构建 - 您将付出巨大努力,但最终您仍需要使用非对称加密的PKI(私钥基础结构)来确保其安全。证书主要是关于包装,存储和传输公钥和私钥。