我正在开发一个WCF服务(NetTcpBinding),它没有安全性就可以正常工作。我们从DigiCert购买了证书并将其安装在服务器上并使用DigicertUtil.exe进行配置。也安装在测试客户端计算机上。
启用安全性我可以从我的开发PC连接到它而没有任何问题。
服务器配置:
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
binding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;
ServerHost.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
Properties.Settings.Default.CertificateName);
客户端配置:
<binding name="EndPointTCP" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="1610612736"
maxReceivedMessageSize="1610612736">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="false" inactivityTimeout="00:10:00" enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign"/>
</security>
</binding>
<behaviors>
<endpointBehaviors>
<behavior name="behavior_ServerService">
<clientCredentials>
<clientCertificate findValue="*.domain.com"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="net.tcp://clients.domain.com:10001/Server/ServerService"
binding="netTcpBinding" bindingConfiguration="EndPointTCP" contract="ServerServiceReference.IServerWS"
name="EndPointTCP" behaviorConfiguration="behavior_ServerService">
<identity>
<dns value="*.domain.com" />
</identity>
</endpoint>
</client>
(我修改了域名和服务名称以保护客户的隐私。)
从任何其他计算机上尝试我在客户端上收到以下错误:
套接字连接已中止。这可能是由于处理消息的错误或远程主机超出接收超时或基础网络资源问题引起的。本地套接字超时为'00:00:59.9840000'。
远程主机强行关闭现有连接
服务器上的跟踪日志显示:
根据验证程序,远程证书无效。
这很奇怪,因为我在服务器和客户端都使用相同的证书......(更不用说它工作得很好的开发电脑......)
即使我设置了
,错误信息也是一样的ServerHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
服务器上的和
ServiceClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
在客户端上。
有人能告诉我如何正确地做到这一点吗?当然,我不想使用像验证回调一样返回true或上述非验证模式的变通方法。
任何帮助将不胜感激。只有这个“小”问题才能解决才能释放...... :(
提前多多感谢!
Hudgi
答案 0 :(得分:10)
听起来您正在尝试使用与服务器和客户端证书相同的证书,并且您的客户端没有与颁发证书相同的主机名。即使您设置X509CertificateValidationMode.None,主机名也必须匹配。如果您的开发机器与服务器相同,那么它肯定会成功。
您是否有意尝试通过SSL对客户端进行身份验证,或者您只是尝试使用证书颁发机构与客户建立信任?
我还怀疑您的证书可能不是真正的通配符证书,如果您在使用该证书进行客户端身份验证时运气不佳。
答案 1 :(得分:1)
如果要忽略自签名或无效的证书,请在客户端呼叫请求之前尝试使用此代码段代码。
ServicePointManager.ServerCertificateValidationCallback = delegate
(object s, X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors) { return true; };
希望对您有帮助。