2011-08-12 59 views
1

我开发了一个应用程序,它启动了几个使用SecurityMode.Message加密通信的WCF服务。WCF认证的SSL证书

它正在工作,但它非常复杂,因为我们必须生成一个SSL证书并将其放入特定存储区,服务器和客户端。

的问题是,将使用该程序的客户:

  • 是不是在一个域(实际上,服务器肯定会在一个域中,而不是客户端
  • 不想买一个证书

那么,什么是我最好的拍摄?我只需要对数据进行加密,我并不需要确保我连接到正确的主机。

我知道我米不在最好的情况,但应用程序将被一些特定的用户使用。

这里是我的代码的一部分,这使得连接:我删除了

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(); 

请注意:

服务器端:

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)); 

客户端部分关于我的自定义验证有一个更干净的代码

回答

4

您的客户希望在Windows域以外的安全性=您的客户需要证书。没有证书=没有安全。这是你必须向你的客户解释的。

您只需要在服务器上拥有带私钥的证书,并且客户端必须信任该证书(如果它信任发布者,则不必安装它)。这是什么意思?你有三个选择:

  • 您的客户必须从信​​任的发布者购买证书和您的客户将只工作
  • 您的客户必须有自己的证书颁发机构安装,这将生成证书和客户端必须有权威的证书在他们信任的根权威商店(每个大公司都有自己的认证中心)。
  • 您将在生产中使用自签名证书。这是“不太安全”,不推荐。安全性较低意味着您的客户必须信任自签名证书并且无法验证证书链=它无法验证该证书是否由受信任的颁发机构颁发,并且无法验证该证书颁发机构是否吊销了受损证书。在这种情况下,您必须在每个客户端上安装服务证书 - 这是信任自签名证书的唯一方式(安装本身实际上是信任)。

这就是安全工作的方式。你可以建立你自己的 - 你会付出很大的努力,但最终你仍然需要使用非对称加密的PKI(私钥基础设施),以确保它的安全。证书主要是包装,存储和传输公钥和私钥。

+0

好吧,这正是我的想法。如果客户更喜欢没有加密并且不需要安装/支付证书(我不推荐他,但我需要知道) 并且:如果他们购买了证书,我有在这里检查吗?我想有些证书只能用于http,否? – J4N

+0

SSL服务器证书将起作用。如果您想制作自己的定制解决方案,则由您决定。你必须在传递它之前加密邮件内容并在收到邮件之后解密它 - 可能是自定义邮件检查器或自定义通道/编码器。您必须找到一种方法来安全地存储加密密钥(这正是证书的作用)。 –

+0

谢谢,另一个问题:如果只能通过客户网络访问服务器,该怎么办?我的意思是,对于可信的出版商?我们可以获得内部网络名称或私有IP的合法SSL证书吗? – J4N