The certs on the server were updated to use new ones which are RSA 4096. WCF clients throw an exception of type: System.Security.Cryptography.CryptographicException with message Invalid provider type specified.
I create a proxy dynamically using ChannelFactory.
In the app.config of the client, I specify the certificate to be used using <clientCredentials> and <serviceCertificate> like so.
<endpointBehaviors>
<behavior name="MyServiceBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
<defaultCertificate findValue="client.cert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCertificate>
<clientCertificate findValue="client.cert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
The certificate is installed on the client. (and the server)
Does WCF support the use of RSA 4096 certificates?
Thanks.
Related
A self-signed certificate is used for authentication in the WCF application. The server specified:
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
...
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/>
</clientCertificate>
The certificate is enabled correctly on the client:
<endpointBehaviors>
<behavior name="wsHttpCertificateBehavior">
<clientCredentials>
<clientCertificate findValue="<Thumbprint>" storeName="My" storeLocation="LocalMachine" x509FindType="FindByThumbprint"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
On the client, the certificate is added to the trusted root certificates. When calling service methods, an error occurs: the calling user's identity was not verified by the service. I don't understand what else you need to specify for verification. If you remove the certificate and specify
<security mode= "None"/>
the client hangs when calling the service method. I don't understand why. I've been fighting this for a week. Please help me!
This is a demo using X.509 self-signed certificate verification:
<system.serviceModel>
<services>
<service name="Microsoft.Samples.X509CertificateValidator.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<!-- use host/baseAddresses to configure base address provided by host -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:8001/servicemodelsamples/service"/>
</baseAddresses>
</host>
<!-- use base address specified above, provide one endpoint -->
<endpoint address="certificate" binding="wsHttpBinding" bindingConfiguration="Binding" contract="Microsoft.Samples.X509CertificateValidator.ICalculator"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<!--
The serviceCredentials behavior allows one to specify authentication constraints on client certificates.
-->
<clientCertificate>
<!--
Setting the certificateValidationMode to Custom means that if the custom X509CertificateValidator
does NOT throw an exception, then the provided certificate will be trusted without performing any
validation beyond that performed by the custom validator. The security implications of this
setting should be carefully considered before using Custom in production code.
-->
<authentication certificateValidationMode="Custom" customCertificateValidatorType="Microsoft.Samples.X509CertificateValidator.CustomX509CertificateValidator, service"/>
</clientCertificate>
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by a client to authenticate the service and provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
This is the configuration file of the service, we need to specify the location of the certificate.
serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.Custom;
serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new CustomX509CertificateValidator();
We custom verify the self-signed certificate.
public class CustomX509CertificateValidator : System.IdentityModel.Selectors.X509CertificateValidator
{
// This Validation function accepts any X.509 Certificate that is self-issued. As anyone can construct such
// a certificate this custom validator is less secure than the default behavior provided by the
// ChainTrust X509CertificateValidationMode. The security implications of this should be carefully
// considered before using this validation logic in production code.
public override void Validate(X509Certificate2 certificate)
{
// Check that we have been passed a certificate
if (certificate == null)
throw new ArgumentNullException("certificate");
// Only accept self-issued certificates
if (certificate.Subject != certificate.Issuer)
throw new SecurityTokenException("Certificate is not self-issued");
}
}
If you need a complete example of this demo you can download it in this link:
https://www.microsoft.com/en-us/download/details.aspx?id=21459
I have created the WCF REST sevice and hosted as windows service. I took the reference from following post.
http://www.codeproject.com/Tips/1009004/WCF-RESTful-on-Windows-Service-Host
Now i am trying to add certificate based authentication on it.
I added the following section inside config file.
note : i followed the following msdn link for adding authetication
https://msdn.microsoft.com/en-us/library/ff648360.aspx
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
and
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="CN=tempCertServer" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
i installed the windows service and when trying to start it. it throws the error.
I removed the following section
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="CN=tempCertServer" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
and error disappear. obviously certification didint work.
What could be the reason?
am i doing correctly adding certificate based authentication for rest service hosted as windows service?
I got the solution.I made following change
<serviceDebug includeExceptionDetailInFaults="true" />
I saw the exception in event view logs. service was not able to find certificate,
hence not started.Again created certificate and it works.
For creating certificate follow following link closely.
https://msdn.microsoft.com/en-us/library/ff648498.aspx
I have testing WCF service and i want to deploy it for development purposes to IIS Express (not classical IIS)
part of my Web.config
</serviceHostingEnvironment>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="test">
<endpoint binding="basicHttpsBinding" contract="WcfService1.IService1" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="test">
<serviceMetadata httpGetEnabled="False" httpsGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceCredentials>
<serviceCertificate findValue="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
When i deploy it on IIS express everything works fine... Except it is on port 44300 (that is ok) but it use IIS Express own certificate generated on iis express installation.
I clearly specify so he should use my certificate located by thumbprint and by value "XXXXXXX...."
How to force IIS express to respect that service behavior part ?
There is a nice blog post by #SCOTT HANSELMAN on this:
http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx
OK so i have a solution.
What i wrote is different kind of certificate - its for service authentication on client.
Certificate used for SSL connection establish is really set with this command:
netsh http add sslcert ipport=0.0.0.0:443 appid={214124cd-d05b-4309-9af9-9caa44b2b74a} certhash=YOURCERTHASHHERE
Azure projects - web roles do this on project startup automaticaly.
We have a WCF service hosted in IIS with the following customBinding. The service receives request from IBM Datapower that is encrypted and signed. The service can verify the signature and decrypt the request fine. But the response sent out is not encrypted or signed. (I can verify this using WCF logging)
<customBinding>
<binding name="myCustomBinding">
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport requireClientCertificate="false" realm="" />
</binding>
</customBinding>
<behaviors>
<serviceBehaviors>
<behavior name="myServiceBehavior">
<serviceCredentials>
<serviceCertificate findValue="{serverCertificateName}" x509FindType="FindBySubjectName"
storeLocation ="LocalMachine" storeName ="My"/>
<clientCertificate>
<certificate findValue="{clientCertificateName}" x509FindType="FindBySubjectName"
storeLocation ="LocalMachine" storeName ="My" />
<authentication certificateValidationMode="None" includeWindowsGroups="false"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors></behaviors>
The MessageContracts have ProtectionLevel set to ProtectionLevel.EncryptAndSign
Am I missing something here?
I am not a WCF expert so forgive me if I am asking below question.
To encrypt and sign a content [in PKI domain] you need to have a private key [and everybody knows that is not included in certificate]. So I am just curious, as to where that private key is specified in above configuration. Is it the case that if you specify the certificate in above configuration, the corresponding private key is automatically picked up [I am just curious because I am not sure what is going under the hood]?
On the contrary when you receive an encrypted content, the only thing you need to verify and decrypt is the certificate [practically in most cases, keeping aside key negotiations that may happen].
Just let me know if this helps? May be this comment is too trivial [kindly excuse me if this is the case].
I am attempting to hit a WCF service endpoint. However, I keep getting the above exception on the server (when I check the logs) whenever I attempt to hit the service.
The service basically has mutual certificate behaviour. It lists a Client certificate and a Service Certificate. Also, It specifies a userPrincipleName under the endpoint\identity section of its web.conf... An example of the config file of a similar set up is shown below...
<endpoint address="<nicelyAddressEndpoint>"
binding="netTcpBinding" bindingConfiguration="customTcpBinding"
contract="<service>" name="<smartSoundingCamelCasedServiceName>">
<identity>
<userPrincipalName value="<example>#yourMother.net" />
</identity>
</endpoint>
would be the endpoint that I described.
<service name="<NiceServiceName>" behaviorConfiguration="MutualCertificateBehavior">
<endpoint address="" binding="customBinding" bindingConfiguration="CustomMCBinding" contract="IServiceContractThatIsntWrittenPoorley"/>
</service>
<behavior name="MutualCertificateBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" includeWindowsGroups="false"/>
<certificate findValue="<CertName>" storeLocation="LocalMachine" storeName="Root" x509FindType="FindBySubjectName" />
</clientCertificate>
<serviceCertificate findValue="<ServiceCert>" storeLocation="LocalMachine" storeName="Root" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
And that would be the service and the behavior.
I am doing what I can to attempt to get data out of this thing. I am running into one sticking point, and I am not sure if it is because I am going about this the wrong way, or that I am close and I just need to get over a minor hurtle. In my client web.config I set up the endpoint behavior similarly...
<behavior name="ClientCertificateBehvior">
<clientCredentials>
<clientCertificate findValue="<XXX>"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" />
<defaultCertificate findValue="<XXX>" storeLocation="LocalMachine" storeName="Root" x509FindType="FindBySubjectName" />
</serviceCertificate>
</clientCredentials>
</behavior>
And this is my endpoint...
<endpoint address="xxx.xxx.xxx"
behaviorConfiguration="ClientCertificateBehvior" binding="customBinding"
bindingConfiguration="CustomBinding_IVPOService" contract="VPOServiceEndPoint.IVPOService"
name="CustomBinding_IVPOService">
<identity>
<dns value="xxx" />
<userPrincipalName value="yyy#xxx.net" />
</identity>
</endpoint>
Now I am getting this exception whenever I attempt to hit this service...
The identity check failed for the outgoing message. The expected identity is 'identity(http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn)' for the 'xxxxxx' target endpoint.
I will note that I have the certificate in the appropriate store listed on my local machine and I have granted the appropriate writes to that certificate. I am to the point where I realize that I am making more trouble for myself here, and I am attempting to figure out what is the right thing to do instead of throwing things against the wall and seeing what sticks. What step am I missing? What is the best way to receive data from a MutualCertificate secured service? How can I best get the right userPrinciplename? I thought it would be what is listed in the servie web.config? Am I going about this in the right way? Am I getting close or just making a bigger mess for myself?