用于WCF验证的SSL证书

本文关键字:SSL 证书 验证 WCF 用于 | 更新日期: 2023-09-27 18:05:37

我开发了一个应用程序,它启动了几个使用安全模式的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();

请注意,我删除了关于我的自定义权限的部分,以便有一个更干净的代码

用于WCF验证的SSL证书

您的客户需要windows域之外的安全性=您的客户需要证书。没有证书=没有安全性。这就是你必须向你的客户解释的。

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

  • 您的客户必须从受信任的发行商购买证书,您的客户端将简单地工作
  • 您的客户必须安装自己的证书颁发机构,它将生成证书,客户端必须在其受信任的根颁发机构存储中拥有该机构的证书(每个大公司都有自己的证书颁发机构)。
  • 您将在生产中使用自签名证书。这是"不太安全的",不建议使用。较不安全意味着您的客户端必须信任自签名证书,它不能验证证书链=它不能验证证书是由受信任的机构颁发的,它不能验证被撤销的证书颁发机构损坏的证书。在这种情况下,您必须在每个客户机上安装服务证书——这是信任自签名证书的唯一方法(安装自己实际上就是信任)。

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