Let's Encrypt for Server and OpenSSL for client certificates - ssl

I've to enable both server and client certificates. My plan is to use Let's encrypt for server and OpenSSL for the client certificate. The reason is that Let's encrypt only provide server certificates. I know that some commercial providers like DigiCert or GlobalSign provide both server and client certificates but that is not the option.
I haven't tried yet but I guess CA doesn't necessarily have to be the same for both certificates. Can anyone suggest a better idea?

If you use OpenSSL you will either have to establish a trusted internal CA or else use self-signed certificates, and ensure that whichever you use is trusted by the server(s). In the end it's cheaper to pay an external CA, then you don't have to overcome any trust issues.
I wouldn't say that Let's Encrypt only issues server certificates. There is no difference between a server certificate and a client certificate. However their authentication method requires a web server.

Related

Sign a CSR with keytool

I have to create an SSL connection between a client and a server. I've created a keypair and signed my public key with my private key. The server won't trust this so I need to get it signed by a CA. I presume that the server will trust a certificate which has been signed by the same CA as was used to sign its own certificate. How do I do the business of creating the signed certificate with keytool? Sorry if this is duplicated information on the Oracle website, but for some reason their pages keep breaking my internet browser.
knowledge so far is based on answer here
I presume that the server will trust a certificate which has been signed by the same CA as was used to sign its own certificate.
Correcting your assumption here: A system trusts various major Certificate Authorities (CA) by default (eg: GeoTrust, Entrust, OpenTrust, Verisign, etc...). When you get your CSR signed by any of these known CA's, the server will trust by default, not just by the CA that signed the server's certificate.
What you could do to test your SSL connection between the client and the server is to work with self-signed certificates.
I've created a keypair and signed my public key with my private key
You shouldn't be doing this as a client. The server is supposed to do this. If the server is working with self-signed certificates, they need to provide the client with that certificate, so that the clients can trust them to make the SSL connection.
As a server, you could use the keytool to create a self-signed certificate. When you are generating a keypair using keytool, it will ask you few attributes like commonName, organizationName, etc... using these attributes, the keytool will create a self-signed certificate and associate it with the private key. All you have to do is export this certificate using the keytool -exportcert command. Once you have done this part, you would use this certificate to secure the server.
Once the server is secured, the server should give or the client this certificate, because it is self-signed and the client's system will not trust it until you explicitly trust it. If the server has secured using a certificate signed by a CA, it need not provide the client with any certificate, because, if it is a known CA, it will already be trusted by the client system.

Restrict TLS mutual authentication to specific TLS certificates

There is a PKI with a single CA issuing all the x509 certificates in my network.
So on my network all the servers and clients possess a certificate from my CA stored in their corresponding keystore together with the private key. Each server and client has also the CA certificate in a chain file available to validate the trust chain of the peer x509 certificate when TLS mutual authentication is going on. All fine.
Let’s suppose I have now on my network two servers and two clients and I want to make sure Client_A and Server_A succeed with TLS mutual authentication using their x509 certificates, as Client_B and Server_B should do.
At the same time, I want to make sure TLS mutual authentication between Client_A and Server_B will not succeed. (Also valid between Client_B and Server_A).
How can I make the servers and clients in my network not only verifying the trust chain, but also respecting some kind of whitelist?
Maybe this is not feasible on TLS Layer, that is what I want to have clarified.
You can achieve this using any of the below 2 approaches-
Verifying client certificate at TLS layer: Create separate intermediate issuing CA for each client group. For example, for all the clients of Server_A, create a CA named Ca_Client_A. So your chain will look like rootCA -> Ca_Client_A -> client certificates. Import this Ca_Client_A in the trust-store of Server-A. Now Server_A will allow connections to the clients which has issuing ca Ca_Client_A. Similarly, you can create Ca_Client_B intermediate CA for serving client group B by server B.
Verifying client certificate at Application layer: For this, you need to write authentication logic in your application server where you need to put constraints such as allowed client certificate-serial numbers or CN name matching with keyword for successful authentication.
Hope that helps.
There isn't any way (that I know of) to do this at the TLS layer.
Most TLS libraries offer a callback option during the certificate exchange, and that would be the appropriate place to check the certificate against a list. Returning the library-specific version of failure/unacceptable will usually cause a TLS handshake failure, and no data will have been transmitted.
A lot of this depends on the server software you are using, not the TLS standard itself. Some software packages can be configured to trust certificates issued by a particular CA certificate. In your scenario, this would allow ANY certificate issued by your CA to connect to ANY server configured to trust your CA certificate. Other server software can be configured to trust a particular certificate, or certificates with a given subject (distinguished name of the certificate, subjectAltName, etc.) So, it depends on which particular "server" you're trying to connect to. Is this an Apache web server? IIS? Tomcat? The answer varies depending on what server platform we're talking about.

SSL approach for private software

What is the proper way of using SSL certificates for private applications? By private I mean that I am the only user, and software is running on my computers.
I want to have a encrypted communication between two of my programs. I want to send passwords between them, so I need to be sure that remote program is not fake/hacked.
As far as I understand I don't need to get paid SSL certificate from the CA, if there is no third party involved.
Is the following correct?
Server has a private key and self-signed SSL certificate.
Client has a copy of server's self-signed certificate (it needs to be well protected).
During the handshake server sends the certificate to client.
client checks if the certificates are the same.
client can start encrypted transmission.
Is there other way?
Server has a private key and self-signed SSL certificate.
Yes
Client has a copy of server's self-signed certificate (it needs to be well protected).
The client has either a copy of the certificate or the certificates public key or the fingerprint of these. Since the certificate is public these information do not need to be protected. Only the private key of the server (residing only in the server side) needs to be protected because using this key one could prove ownership of the certificate.
During the handshake server sends the certificate to client.
Yes.
client checks if the certificates are the same.
Kind of. It might check the certificate or the public key or the fingerprints.
client can start encrypted transmission.
Yes.
I would recommend that you read the OWASP article about certificate and public key pinning. It also contains sample code for various environments.
Client has a copy of server's self-signed certificate (it needs to be well protected).
Clients do not have copy of the server certificate. They get it in SSL handshake
client checks if the certificates are the same.
NO! Clients will have the public certificate of the Certificate Authorities who would have signed the server certificate. They will validate the server cert with the CA cert including things like certificate expiry, CRLs. Not compare for 'sameness'
In your case you are using the self-signed certificates. The clients should be made to ignore the self signed certificate and proceed with SSL handshake.
I would recommend you read through SSL handshake sequence again.

Is it possible to prevent man-in-the-middle attack when using self-signed certificates?

I'm not sure is similar question has been asked before (I couldn't find any), but is it possible to protect Client/Server from Man-In-The-Middle attack?
I'm writing a Client application to communicate with Server. Communication will be SSLv3 based.
I am OK with server's self-signed certificates, but worried about someone else generating same self-signed certificate in the same server name and pretend to be it. My Client application uses OpenSSL library. [Client and Server are thrift based, if it makes any difference]. Can I avoid such attack at the same time maintaining support for self-signed certificates?
Yes.
In short, a self signed certificate is more insecure than a CA certificate only when the client does not know the certificate in advance and therefore has no way to validate that the server is who it says it is.
If you add the self signed certificate to the client and don't accept any other certificate, you're actually as secure (or, one could argue, even more so) than having a certificate authority signed certificate.
The important parts to keep SSL secure with or without a certificate authority are;
The server private key (and in the case of a CA, the private keys of all its roots) is kept secret.
The client knows the server certificate (or its CA root).
You can hard-code the server's certificate and compare it against what you receive.
Or better yet, create a CA certificate and server certificate, signed by the CA. Have the CA trusted on the client (again by hardcoding it in your application) and validate received server certificate using the CA certificate.
If you can protect your private keys well enough, a middleman will not be able to masquerade as you, assuming the user actually looks at the certificate. The problem with self-signed is that if you want the user to add the exception to their browser, or just ignore the warning, then you are exposed to man-in-the-middle attack, because anyone else may create their own certificate.
Of course, "protecting your private keys well enough" is not trivial at all. When you pay for a "Verisign" certificate, you're not paying for their software creating the certificate - you're paying for the security forces they have guarding the building in which the private keys are stored.
That's easy! NOOOO !!! Not anymore than you could prevent a man-in-the-middle attack from certificate issued-by a well-know authority. >:)

Apache Tomcat SSL problem

I'm trying to configure Apache Tomcat to use SSL connection with client authentication (two way authentication). My certificates are CA signed.
If I put CA certificate, together with client certificates, in tomcat truststore everything is OK. If I don't put CA cert in tomcat truststore, Tomcat won't trust to clients.
Do I need CA certificate in tomcat truststore?
If I put CA certificate in truststre then Tomcat will trust to every client that have certificate signed by the same CA.
Yes, you need the CA in the truststore. If you are unwilling to put the CA in the truststore, you should not use the CA.
Regarding your last paragraph, you could also examine the Distinguished Name of the client certificates for further authorization.
You are confusing trust, or authorization, with authentication. The only purpose of SSL certificates is to prove that the peer is who he says he is, i.e. establish his identity. You need to decide whether or not you trust that CA's procedures for verifying identity prior to signing CSRs, and if so put its certificate into the truststore.
Whether you want that identity to access parts of your system is a completely different question which you must solve in a different way, via a database of roles granted to identities. This is something that LDAP is particularly good at, but you can also use a DBMS or even an XML file in Tomcat. Have a look at Tomcat Realms for how to do this.
What you mustn't do is attempt to use the truststore as that database. That's not what it's for, and not the purpose for which it or PKI was designed. Which is why you're having problems trying to use it that way.