WCF certificate credential over transport security needs client to send pfx file in order to work properly.
pfx files contain both public and private key.
I'm pretty sure client should not share its private key.
What did I get wrong ?
WCF Client do not send pfx file.
It needs both public and private key in order to authenticate, but only public key is sent during authentication protocol.
Related
I am not able to authenticate my WCF service using the .cer certificate. The same service is authenticating with the .pfx certificate. The client is not willing to share the .pfx file and insists that I implement a way to use the .cer certificate. The .cer certificate I have to use is without the private key.
I have tried installing the certificate and exporting it in the .pfx format but since the .cer file is without the private key, the option to export in .pfx is disabled.
I am using the following to fetch the .pfx certificate:
((X509CertificateClaimSet)OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets[0]).X509Certificate;
I want to know if the .cer certificate can be used instead of .pfx and if through the same code, I can fetch the .cer certificate as well.
I am not able to authenticate my WCF service using the .cer certificate. The same service is authenticating with the .pfx certificate.
this is expected and by design. Authentication process requires private key, which exist in PFX and doesn't exist in .cer. Private key is used to sign authentication data and to prove certificate ownership.
The client is not willing to share the .pfx file and insists that I implement a way to use the .cer certificate.
Your client asks for impossible and potentially doesn't understand how certificate-based authentication works. There is no way to make it working with public certificate, you need a PFX with private key.
Maybe you can create your own certificate with private key and share public certificate (without private key) with client so they can install it in their app and trust it. However it depends on applications and their configurations.
I am developing a service which I will deploy behind an ssl terminating proxy inside a private network.
SSL is NOT used inside the private network.
The client of my API wants to pass their certificate in a header. We are NOT going to use mutual TLS.
Once my service receives a request with a certificate in a header, how should I validate it?
My understanding is that:
The client's certificate will contain their identity, public key and a signature of a Certificate Authority.
Once I receive their certificate I should be able to verify that it is indeed legit with the public key of a Certificate Authority.
But how should I verify that the client is who they claim to be and not simply replaying the certificate? I could, in theory, challenge their certificate by encrypting something with their public key and then asking them to decrypt it but this will require additional steps.
Client will also send some signed content (say signed userid or signed token) and you can use public key to verify signature. If Signature is verified, it proves that sender owns the private key for the public key he had sent.
I am trying to extend WCF by following this how-to guide from microsoft. The basic idea is to use a hardware security module as the client-side private key holder, which means all cryptographic operations involving the client's private key must be carried out by the security module chip.
Setup
dotnet framework: 4.7.2
binding: netTcp
binding security: Message
clientCredentialType: Certificate (X509Certificate2)
serverCertificate: X509Certificate2
All certificates ( 1 server cert and 2 client certs ) are signed off by the same CA. The server certificate is a normal pfx file that contains both the certificate and private key. I prepared two different client certificates one with the private key and one without the private key. (two client side pfx files have the identical certificate )
Observations:
When using the client pfx file contains the private key, the client is able to communicate to the server in the mtls fashion.
When using the client pfx file without the private key, the attempt to set up secure session fails with the following exception
System.ArgumentException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
The certificate '<cert name>' must have a private key. The process must have access rights for the private key.
Stack Trace
System.ServiceModel.Security.TlsSspiNegotiation.ValidatePrivateKey(X509Certificate2 certificate)
System.ServiceModel.Security.TlsSspiNegotiation..ctor(String destination, Boolean isServer, SchProtocols protocolFlags, X509Certificate2 serverCertificate, X509Certificate2 clientCertificate, Boolean clientCertRequired)
System.ServiceModel.Security.TlsnegoTokenProvider.CreateTlsSspiState(X509SecurityToken token)
System.ServiceModel.Security.TlsnegoTokenProvider.CreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout)
System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
In neither case, the provided CustomX509AsymmetricSecurityKey as per the how-to above was NOT used by the WCF framework. Did not even instantiate the class. The CustomX509SecurityToken was instantiated via the CustomX509SecurityTokenProvider. But the SecurityKeys property of the CustomX509SecurityToken class was never called, which is where the custom private key comes to play.
Questions
Is the how-to guide out of date? Notice it is dated 03/30/2017.
The exception when using the pfx without private key is sort of self-explanatory. I did not provide the private key. Why didn't WCF use the provided CustomX509AsymmetricSecurityKey as the private key? Isnt this the whole point that the user is providing an alternative private key in the form of a X509AsymmetricSecurityKey?
Am I following the wrong guide to achieve what I want? I did try to set the PrivateKey property of the X509Certificate2 class with a custom RSA implementation. But got lost trying to implement the ICspAsymmetricAlgorithm interface which is required by the X509Certificate2.PrivateKey
Please help me fill out the blanks here -
The server keeps its private key and the public key is shared to the users. So the client trusts the content thats coming from the server using the public key. How does the client encrypt the contents he is sending back to the server ?. Using the public key of the server ? or does the client send a autogenerated private key and encrypts it using the public key which is then decypted by the server along with the message and used for furthter communication by both parties.
A Public and a Private key is required to do ssl communication. This Key pair is generated using a self signed certificate ?. How can a single self signed certificate contain both public and private keys.
One more thing On message level security -- im looking at a current configuration and am pulling my hair out -- Using IBM Ikeyman to look at the producer and Consumer JKS files-- for Message level security(Digital Signing) there is a Personal certificate at the Consumer and a Signer certificate at the Producer ... Isnt this the other way around? Is this current configuration incorrect --- Both the keys are same by the way.
The server keeps its private key and the public key is shared to the users.
Correct.
So the client trusts the content thats coming from the server using the public key.
No. There is no 'so' about it. The client trusts the server certificate because it is signed by someone he trusts, and he knows it belongs to the server because the server provides a digital signature that the client can verify, which only the private key owner can do. Therefore he knows that the server owns that public key.
How does the client encrypt the contents he is sending back to the server ?.
The client and server negotiate a shared session key independently using techniques described in RFC 2246. For the most part they don't involve PKI at all.
Using the public key of the server? or does the client send a autogenerated private key and encrypts it using the public key which is then decypted by the server along with the message and used for furthter communication by both parties.
Neither, see above. This is quite a large subject.
A Public and a Private key is required to do ssl communication.
No. One of the parties must have a private key and a corresponding certificate that the other party trusts, otherwise the communication is insecure.
This Key pair is generated using a self signed certificate
No. The statement doesn't even make sense. Key pairs are generated first, nothing to do with certificates yet. The certificate is a wrapper for the public key.
How can a single self signed certificate contain both public and private keys.
It can't, and it doesn't. Self-signing doesn't have anything to do with it either.
Public-key encryption 101:
The public and private keys form a pair: each key in the pair can decrypt messages encrypted with the other, but cannot decrypt messages encrypted with itself. If the client can decrypt a message with the public key, it knows the message was encrypted by the owner of the public key. Conversely, a message encrypted with the public key can only be decrypted by the owner of the private key.
The basic idea is that the client generates a key for a symmetric-key cypher, encrypts it with the public key, and sends that to the server. Both sides then use that symmetric key and cypher for the majority of the communication.
In SSL communication,when the client wants to interact with some server, the server sends its public key. Always remember a certificate is nothing but a public key with a bunch of supporting information.
The problem here is any hacker can masquerade as a server and can block the communication between server and client. So the server certificate must be signed by some certificate authority. The client only believes the server certificate if it is signed by a certificate authority.In that case the hacker in between can not masquerade as a server because its certificate will not be authenticated by the certificate authority.
So client accepts the certificate and gets the public key of server. Now the client can send its public key encrypted by the public key of the server. Since this encrypted message can only be decrypted by the private key of the server so only server can decrypt it.
But the use of public key and private key over the ssl communication can slow down the connection very much because these keys lengths are 1024 or 2048 bits.
So practically what happens is instead of sending its own public key, the client sends the symmetric key encrypted by the public key of the server. Server decrypts it with its private key and it gets to know the symmetric key. Now the further communication happens with this symmetric key encryption and decryption.Since no third party gets to know the symmetric key, the communication will be secure.
Remember symmetric key lengths are generally 64-128 unlike public keys hence less the time for encryption and decryption.
I am hosting a secured WCF service which is a wrapper over an existing ASMX service.
My service needs have certificate authentication (transport level security, same as in the original service). My problem is that the users will be using client certificates issued by original service And not my new certificates.
To my knowledge you can not customize certificate authentication over Transport level security. But there must be some way to use third party cert authentication/encryption here
Does anyone having idea on how to make it possible in this case?
How can you have a digital certificate without a public key? Digital certificates rely on asymmetric cryptography. If you don't have the public key file, then you can export it from the certificates you do have - but they most certainly do have public keys.