WCF SSL certificate using an enterprise CA

匿名 (未验证) 提交于 2019-12-03 09:06:55

问题:

For an application, I need to have a SSL certificate for a WCF service,

So we installed it. If I go with an internet browser with a web browser trough https, I've got no problem, no warning, nothing, so I suppose that this certificate is considered as valid for windows.

The problem is that when I'm trying to connect to my WCF server, I got this error:

The X.509 certificate CN=myHostName, OU=tom, O=myDomainName, 

L=MyLocation, S=SO, C=CH chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. The revocation function was unable to check revocation because the revocation server was offline.

What can be wrong? How can I know which part of the chain is unvalid? Is there any way to know what is the missing part?

Here is my code The server:

ServiceHost myHost = new ServiceHost(typeof(MyService)); 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;  //we set the security type binding.Security.Mode = SecurityMode.Message; binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;  //we set the server's certificate myHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, ConfigurationManager.AppSettings["Hostname"]); myHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; //we add the endPoint(and we indicate which methods are exposed through the interface  myHost.AddServiceEndpoint(services[port], binding,                  String.Format("http://localhost:{0}", port));     //Some services doesn't need an authentication if (!servicesWithoutAuth.Contains(services[port])) {     //We set the authentifier:     myHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;     myHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();     myHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;       //we set the AuthorizationPolicy     List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy> { new CustomAuthorizationPolicy() };     myHost.Authorization.ExternalAuthorizationPolicies = policies.AsReadOnly(); } else {     //We set the authentifier:     myHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;     myHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new NoUserNamePasswordValidator(); }  //We bypass the certificate verification(our certificate is only self signed) //HACK Only to desactivate the SSL check:  ServicePointManager.ServerCertificateValidationCallback += ValidateCertificate;    //HACK: Remove when debug finished private static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors) {     return true; } 

My client side:

// the remote adress is of the form "net.tcp://localhost:8000" string remoteAddress = String.Format("{0}://{1}:{2}", Tools.GetDescription(accessInfo.ServiceHost.Protocol), accessInfo.ServiceHost.HostName, accessInfo.PortNumber);  // HACK: binding depends on protocol -> switch over accessInfo.ServiceHost.Protocol  // 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);  channelFactory.Credentials.UserName.UserName = ((UsernamePasswordAuthentication)authInfos).Username; channelFactory.Credentials.UserName.Password = ((UsernamePasswordAuthentication)authInfos).Password;   //We set the maxItemsInObjectGraph foreach (OperationDescription op in channelFactory.Endpoint.Contract.Operations) {     DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();     if (dataContractBehavior != null)     {         dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;     } } SamlSecurityTokenAuthenticator authenticator = new SamlSecurityTokenAuthenticator(new List<SecurityTokenAuthenticator>(new SecurityTokenAuthenticator[] { new RsaSecurityTokenAuthenticator(), new X509SecurityTokenAuthenticator(X509CertificateValidator.None) }), TimeSpan.FromDays(5));  _service = channelFactory.CreateChannel(); 

回答1:

How can I know which part of the chain is unvalid? Is there any way to know what is the missing part?

Well, from my experience, if you open your keystore and view it, you should see that your certificate clearly forms a chain. I don't know what tool you use to view your keystore (or if your using the windows keystore), but when you view your key, you should see a chain of some kind. If a chain is formed correctly, it will appear correctly, and doesn't have any missing parts.

My guess is that when you imported your certificate reply, it didn't form the chain for some reason. In other words, your certificate is in your keystore as a "unchained" public key.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!