I realize the number of question about SSL certificates is legion, but after much searching I couldn't find a precise answer to the following confusion.
For one-way SSL, under what circumstances does the consumer of an HTTPS web service need to import the provider of said web service's certificate/public key? I've consumed a few web services over https before and never had to add the other company's certificate or public key to the key store (or is it trust store?) of any device at my company.
And yet apparently sometimes that is the case, as evidenced by these examples:
certificate mechanism between webservice provider and consumer
Consuming RESTful service over https with certificate using Java
Is it only necessary when the provider of the service's certificate is not issued by a CA known to the consumer?
Also, if the consumer does end up having to import the provider's certificate, AND it's the case that the consumer's consuming app itself consists of a client part and a server part, does the consumer import it into the store of the consumer's web server or into the store of each and every client computer at the consumer's company?
Finally, for two-way SSL, does the consumer send his own client certificate with code that executes on his (possibly many) client computers or on his own web server?
Thanks for any clarification.
Is it only necessary when the provider of the service's certificate is not issued by a CA known to the consumer?
yes. When relying party uses certificates from a globally trusted CA, there are no extra actions required to install foreign certificates.
into the store of each and every client computer at the consumer's company?
if issuer is not globally trusted, it must be installed on every device that consumes service with custom certificate.
does the consumer send his own client certificate with code that executes on his (possibly many) client computers or on his own web server?
it's unclear what do you mean. Can you elaborate?
update:
It depends on how 3rd party server authenticates you. Are they ok to identify your app as whole or they require to distinguish every internal user. In first case, it is enough to have single client certificate within your app and you will have two separate TLS connections:
3rd party server <--TLS--> Your App <--TLS--> End user (many)
End users connect and authenticate only on your application. When necessary, your app establishes a separate TLS connection to 3rd party and work is done. It is quite common practice. End users are not aware of 3rd party server and 3rd party server is not aware about your internal users (and probably should not be).
Related
I'm working with an old legacy app at work that's written in ASP.NET 4. We recently started migrating to the cloud and we had to expose one of the endpoints so that our api gateway (Apigee) can call it. What is the correct way to restrict this endpoint so that it only allows calls from Apigee? I'm aware 2-way-ssl should solve this issue but that requires changes on the Apigee side and we don't have control over that. Is there something I can do on the API side to confirm that the certificate in the request is specifically from Apigee?
You're describing the need for what is sometimes called 'southbound' authentication. Specifically mutual-TLS sometimes called client authentication, as opposed to standard (or one-way) TLS where only the server is being authenticated by the calling client. You're right: mTLS (a.k.a., "two-way SSL") is one means to allow your back-end server to authenticate the calling Apigee-layer 'client'.
When you want client authentication via TLS (mTLS) you need to configure your back-end server endpoint to require mTLS at the time of the handshake, and to have stored in its Truststore the signing CA certificate of the client certificate you expect to see offered up by the calling client at time of connection. Done right, your server
requires mTLS and shuts down the handshake if the client won't
offer a client cert,
validates the client cert is authentic as being issued by a recognized signing CA (Truststore), and
is the actual client cert expected to be seen (e.g., by matching the expected distinguished name).
Here's an authoritative support-community article about doing all this, within Apigee: https://community.apigee.com/questions/63337/mutual-tls-between-client-to-edge-and-edge-to-back.html
There is a server with WCF client, which periodically initiates communications over internet with many WCF services installed on our clients computers. WCF services and WCF clients are hosted in Windows Service, current binding is basicHttpBinding.
Communication has to be over https with mutual authentication. Company ordered SSL certificate but it is not clear if this certificate can be installed on clients computers (because WCF service is there) without exposing a private key. Binding can be basicHttpBinding or wcHttpBinding with transport or message security but using certificates.
Is it possible to install service-side certificate on client computers and client-side certificate on our server? Should this architecture be re-worked so WCF service is on our server or it is possible to secure somehow this current solution?
Each computer involved requires it's own certificate. A certificate value for authentication relies on the uniqueness of the private key. The private key never leaves the host machine, and the certificate can be used to authenticate said machine (because is the only one in the world that posses that private key). As soon as you start distributing copies of a private key, security is pretty much compromised.
Normally such deployment rely on PKI infrastructure which can create certificates on-demand and sign them with a trusted key.
What product/protocol the certificates are used for is irrelevant. What kind of WCF HTTP binding you use it maters not.
I think there's a gap in my mental model of WCF authentication, hoping someone can help me fill it in.
So, I'm creating a WCF service and would like to have clients authenticate using certificates, and message-level security. I'd like the service to validate these using chain trust so that I don't need each client cert installed on the service. For now, I'm not interested in having the service authenticate to the client.
Here's my understanding of what's needed to do this:
The client needs a certificate signed by a CA that's trusted on the service side.
The service needs a CRL installed for that CA.
The service config should have message security turned on, specify clientCredentialType="Certificate", and chain trust for client certificate validation.
The client config should have message security turned on, specify clientCredentialType="Certificate", and an endpoint behavior that tells how to find the client certificate in the store.
The client makes a request to the service, sending its certificate. The service sees that the client's cert is signed by its trusted CA and lets the request through.
Now, all of the walkthroughs of this process I've found also include a step of creating a certificate for the service. None of them explain what this is for, which is throwing me. Why is a service certificate needed if I just want to authenticate the clients?
You are right. In theory no server certificate is required, in practice wcf enforce you to use one. The good news is that you should use a dummy certificate for the server and also set ProtectionLevel to SignOnly. I suggest to read this article which talks on a similar scenario and mostly relevant.
I am somewhat confused as to how two-way SSL works. How does the client create its certificate to send to the server? Is it generated from the server and distributed to the client?
Also, what is the advantage of two-way SSL over one-way SSL?
Both certificates should exist prior to the connection. They're usually created by Certification Authorities (not necessarily the same). (There are alternative cases where verification can be done differently, but some verification will need to be made.)
The server certificate should be created by a CA that the client trusts (and following the naming conventions defined in RFC 6125).
The client certificate should be created by a CA that the server trusts.
It's up to each party to choose what it trusts.
There are online CA tools that will allow you to apply for a certificate within your browser and get it installed there once the CA has issued it. They need not be on the server that requests client-certificate authentication.
The certificate distribution and trust management is the role of the Public Key Infrastructure (PKI), implemented via the CAs. The SSL/TLS client and servers and then merely users of that PKI.
When the client connects to a server that requests client-certificate authentication, the server sends a list of CAs it's willing to accept as part of the client-certificate request. The client is then able to send its client certificate, if it wishes to and a suitable one is available.
The main advantages of client-certificate authentication are:
The private information (the private key) is never sent to the server. The client doesn't let its secret out at all during the authentication.
A server that doesn't know a user with that certificate can still authenticate that user, provided it trusts the CA that issued the certificate (and that the certificate is valid). This is very similar to the way passports are used: you may have never met a person showing you a passport, but because you trust the issuing authority, you're able to link the identity to the person.
You may be interested in Advantages of client certificates for client authentication? (on Security.SE).
What you call "Two-Way SSL" is usually called TLS/SSL with client certificate authentication.
In a "normal" TLS connection to example.com only the client verifies that it is indeed communicating with the server for example.com. The server doesn't know who the client is. If the server wants to authenticate the client the usual thing is to use passwords, so a client needs to send a user name and password to the server, but this happens inside the TLS connection as part of an inner protocol (e.g. HTTP) it's not part of the TLS protocol itself. The disadvantage is that you need a separate password for every site because you send the password to the server. So if you use the same password on for example PayPal and MyPonyForum then every time you log into MyPonyForum you send this password to the server of MyPonyForum so the operator of this server could intercept it and try it on PayPal and can issue payments in your name.
Client certificate authentication offers another way to authenticate the client in a TLS connection. In contrast to password login, client certificate authentication is specified as part of the TLS protocol. It works analogous to the way the client authenticates the server: The client generates a public private key pair and submits the public key to a trusted CA for signing. The CA returns a client certificate that can be used to authenticate the client. The client can now use the same certificate to authenticate to different servers (i.e. you could use the same certificate for PayPal and MyPonyForum without risking that it can be abused). The way it works is that after the server has sent its certificate it asks the client to provide a certificate too. Then some public key magic happens (if you want to know the details read RFC 5246) and now the client knows it communicates with the right server, the server knows it communicates with the right client and both have some common key material to encrypt and verify the connection.
In two way ssl the client asks for servers digital certificate and server ask for the same from the client. It is more secured as it is both ways, although its bit slow. Generally we dont follow it as the server doesnt care about the identity of the client, but a client needs to make sure about the integrity of server it is connecting to.
I have a client/server WCF application that needs some sort of user authentication against a database. The application (both client and server together) is being developed to be sold to dozens of customers, for use on their intranets. We're not too worried about encrypting most of the data moving across the wire, except of course during authentication.
Thinking about WCF security, I keep coming back to the idea that we should be making use of x509 certificates. However, our customers will definitely not want to know about any of the details of having to apply for, purchase and install these certificates.
I'd like to know first of all what the preferred method is of implementing username/password authentication in this scenario. If it will require using certificates, must the customer apply for their own certs from a trusted CA, or can we as the software provider generate certificates for the customer to use?
Really I'm looking for a best practice, with the least friction to our customers.
Thanks!
Edit: I'm using NetTcpBinding, and my server is running as a Windows Service.
So username/passwords does not require client certificates as I'm sure you're aware, it simply requires an HTTPS certificate on the server hosting the WCF service - once you have that you can happily use the standard username/password auth bits (WCF will not allow message based authentication without HTTPS).
If you wanted to head down the client certificate root you get the advantage of non-repudiation - you can be sure that the machine sending is who it says it is (unless someone has stolen the certificate, which is less likely than a username and password combination going walk about). You as the software provider could act as your own certificate authority and generate your own client certs (there are a few ways to do this depending on your infrastructure) but then you need to configure the clients to trust your root CA.
If the server and client are running in a domain environment you could use transport security with Windows authentication (you're using tcp binding, so interoperability is out the window anyway!) The added bonus to this is the authentication is transparent and you don't need any certificates anywhere. If you want verfication of the server identity then message security with Windows authentication will do the trick.
I've got project in production which is similar to your scenario. I have a Windows Service hosting endpoints via netTCPBinding and I used x509 certs... although in my case, the intent was to encrypt both the transport and message layers, as I was crossing over untrusted security boundaries. I was less concerned with providing authentication/authorization other than requiring the certificate be present.
Similar to your intranet scenarios (I'm assuming), I had authority over the server and client machines at installation time... or at least could dictate some of the terms of installation.
Rather than purchase the x509 certs and burden the client with that expense, I opted to roll our own. We set up one of our Win2003 servers to be a CA, issuing our own Certification Authority cert. We then generated an x509 cert for the server, as well as individual x509 certs for the clients.
The client and server certs were installed on both clients and server (as appropriate) into the personal user store at the computer level. We also installed our CA cert directly into the Trusted Root Certification Authorities section, thus making our client and server certs trusted.
Because I was less concerned with authentication/authorization, I don't know what to recommend as a best practice for dealing with binding certs to individual users and going more granular than machine-level (my solution was windows service to windows service communication -- completely unattended). I would think you'd need a cert for each user, installing it into their personal user store in the certificates MMC. The runtime implementation will be guided by how you configure WCF to do the cert lookup, so it should be fairly easy.
Throughout the process, I relied heavily on what I'd learned from this great CodeProject article: Securing WCF Services with Certificates. It walks you through generating/installing the certs. The sample WCF applicatoin is IIS-hosted, but I was able to pretty easily translate the config sections from web.config to app.config.
In my case, I exposed the Web interface for requesting certificates in Win2003 to the web itself, so the client could request certificates directly in the future. We have approval control, so it works well. I haven't had a need to generate new certs yet, so I can't say how much friction that would entail.
If your going to be crossing firewall boundaries then certificates are going to be your best solution. I don't know much about the specifics about applications for certificates or your application. Unfortunately, as far as i know, i think you will have to help them apply for certificates or they will have to do it their self unless they want to undertake in the process of installing their own certificate server. If the app will be internal then windows authentication will work and is VERY easy but if you think your going to have clients that user your application across firewall boundaries then you might as well invest the time in using certificates because certificates will work everywhere. Now there is something called federated security where you delegate the permission of authentication to another entity. I think this is used if say you have to domains and you want to delegate permission say of someone on another domain that is not on your domain to their domain but its pretty complex and my understanding of its very limited but by the sound of your requirements certificates is the way to go.
Security is not supposed to be easy :)