How SSL works in case of self signed certificates in Java - java

I am working on a HTTPS service which will be deployed on a server with a self signed certificate and a client which will accept all certificates.I am new to SSL.
I have gone through this post and this post and understand how to configure trust manager to accept all certificates.
If I understand correctly a java client will use server's public key(installed by using server's public certificate) to encrypt data to be sent to a server.And a server then uses it's private key to decrypt the data.
My questions are:
1.In a common scenario ,we install the server.cer in truststore of client machine(cacerts in java). How does the java client code links to this installed public key to encrypt data while communicating to such server? Who does the SSL encryption here? Is it Java APIs that do it or do i have to handle encryption in my client code before sending data to server?
2.As given in one of the above mentioned post ,we can make client accept all certificates.How will the encryption and decryption work in this scenario? How will the client know which public key to use for encryption as we are not installing any server specific key in client's truststore?
I am looking for more technical details.

I am working on a HTTPS service which will be deployed on a server with a self signed certificate and a client which will accept all certificates. I am new to SSL.
Clearly. You're working on an insecure system. It's a waste of time. You may as well not use SSL at all. The client should accept this certificate and all CA certificates, not all certificates. As described, your system is vulnerable to man-in-the-middle attacks.
If I understand correctly a java client will use server's public key(installed by using server's public certificate) to encrypt data to be sent to a server.
You don't. It doesn't. The certificate is used to authenticate the identity of the server, but SSL encryption is symmetric via a secretly negotiated session key and has nothing to do with the public key in the certificate.
And a server then uses it's private key to decrypt the data.
No.
How does the java client code links to this installed public key to encrypt data while communicating to such server?
Usually via the javax.net.ssl.trustStore property, but again it doesn't use that for encryption, only for authentication.
Who does the SSL encryption here? Is it Java APIs that do it
Yes. It is done by HttpsURLConnection using a javax.net.ssl.SSLSocket.
or do i have to handle encryption in my client code before sending data to server?
No.
As given in one of the above mentioned post ,we can make client accept all certificates.
You can, but it is radically insecure and should never be done that way.
How will the encryption and decryption work in this scenario? How will the client know which public key to use for encryption as we are not installing any server specific key in client's truststore?
See above, you have a misunderstanding here, but when you accept all certificates you have no idea who you're talking to, so any encryption is completely pointless anyway. Don't do this.

Related

Glassfish Https on Servlet without server delivering public keys?

Is it possible to create a HTTPS connection to a java-servlet with a static name (like https://.../logonServlet) so that only clients who already own the public key/certificate can access the servlet? I would like to prevent the server from delivering public certificates and refusing all other clients?
To my knowledge:
I read about the java keytool and the different stores (keystore (certs and private keys) and truststore (client side, public keys)). I am currently reading the book "Glassfish Security" by Masoud Kalali to learn about user groups and different security realms and stuff like different xml options for server configuration but I feel like I start mixing everything in my head so I would like to ask if you could help me with my desire from above.
A big question that is still open to me is "Why do we need certificates?". Shouldn't be a private key which will be kept secret enough and a public key for the clients?
#Edit
What you may want to check is SSL/TLS with client authentication. In this setup, the clients need a certificate and a private key as well. The server will refuse connections if they are not from a client with a trusted certificate. This means that server and client need both a keystore and a truststore.
Seems like you are correct, that is what I am looking for.
Asymetric cryptography works with two elements by design:
Public key: Shared with everybody, so they can know it's you who send the messages. Also to cipher messages that only can be read with the private key.
Private key: Only known to you, so you can guarantee that you are who send the messages. Also to read messages sent to you ciphered using your public key.
In a typical HTTPS setup, the server has the certificate (with a public key) and the private key, but the public part is shared with anyone who connects (you can see the certificate of any HTTPS site in the browser).
This is because usually, the client needs to know who the server is, but the server doesn't need to know who the user is (and if it does, other ways like passwords are cheaper and more convenient for the average user).
Sharing the server's public certificate is necessary for SSL/TLS to work, so there is no way to hide those keys and completing the handshake at the same time.
So no, the server's public key cannot be used to authenticate the clients, as it is assumed by design that everybody can get it.
What you may want to check is SSL/TLS with client authentication. In this setup, the clients need a certificate and a private key as well. The server will refuse connections if they are not from a client with a trusted certificate. This means that server and client need both a keystore and a truststore.
Note that keystore and truststore are conceptual terms. A single file (.jks, for example) can act as both, as it can contain private keys and public certificates at the same time. That said, they tend to be in different files.

OkHttp SSL Certificate

So i am developing an app which uses a rest connection to a database server. This server uses TLS encryption and has a SSL certificate. Im using OkHttp3.2 to manage my server connection. I can connect to the server without any problems and also encryption works fine.
My question is based on the certificate tester from java's SSL Engine. I can readout everything the Server send about the certificate (Serial, Signature...) but i cant see any information about validation or trust level like a certificate chain.
Does the SSL Engine tests the Certificate independently or do i have to do this manually?
And would OkHttp's certificate pinning do the Job?
And how would i readout the SHA checksum of the certificate like some ssl tester do? e.g. ssllabs.com
So Thanks to Pravin's comment i think i know everything i need.
If someone is intrested a little conclusion of the article:
Android's SSL Engine checkes validity of the Certificate at every Request. The Certificate is compared with trustet root certificates in local system storage (Settings -> Security -> Trusted credentials).
Certificate pinning would add a second security level, in fact it checkes if a certificate in the certificate-chain has a fringerprint which is equal to your setting. Usefull if you would only want to allow a certifiace of a specified provider to communicade with your app.

Get certificate by alias in keystore with multiple entries in Java

Ok! We are trying to implement a client server aplication (chatroom) . Of course the server is multithreaded. We wanted the communication to be secure so we used ssl sockets and certificates. I have read that you can store multiple certificates and keys in one keystore. When a client enters the chat he needs to fill in his username.
Do we have to connect the username to the alias of the certificate/key?
If yes, how can we use the specific certificate/key from the keystore from the alias? Or is there another way? I mean how can we "pick" the specific certificate depending on the name
Is there a way for the clients to create their certificates at the time of they enter? (We want the certificates to be signed by a CA we have already implemented)
Thank you!
Basically what you want is Mutual or 2 way SSL. Read these for more information - here and here
In short - the SSL communication works (in context of certificates for authentication) is server will send the certificate to the client and if that certificate is present in the client's certificate store or Java's keystore in your case, then it authenticates the server.
Typically server never asks client to send certificate but in your case you wants it so it makes it Mutual or 2 way SSL. So, while handshake process, server will ask client also to send its certificate and it will also check in its keystore if that certificate is present, if so then it will be happy else it will end SSL handshake.
What you need:
Your each client and your server should have a valid certificate.
Your server should have those client certificate present in its "trust keystore", so that it can authenticate client.
Your each client should have server's certificate in its "trust keystore", so that it can authenticate server.
Your server should be configured to support 2 way SSL. Read here for Weblogic.
Answering your questions specifically:
Do we have to connect the username to the alias of the
certificate/key?
No, only this you want is that client certificate should present in the server's "trust keystore". But since your client app and server is on same machine, so I would recommend that have different JVM's installations to run client and server so that you have support different certificates.
If yes, how can we use the specific certificate/key from the keystore
from the alias? Or is there another way? I mean how can we "pick" the
specific certificate depending on the name
Not applicable.
Is there a way for the clients to create their certificates at the
time of they enter? (We want the certificates to be signed by a CA we
have already implemented)
Certificate should be prepared beforehand, and certificate creation and signing is a complex process, you have to generate a CSR etc.
Please do read my this answer for other details you may require while doing all this.

How to switch SSL Verify off for Neo4j's RestGraphDatabase?

I'm running my NEO4j HA cluster behind SSL.
I'm writing a client in Java that manages some data. Now since I'm only using SSL to encrypt communication, I'm using a self-signed cert. But now I'm facing an
uglycom.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException
Any ideas how to tell Neo4J not to verify the cert?
You do not need to generate a self-signed certificate on your own, Neo4j will do that for you when configured to do so.
http://docs.neo4j.org/chunked/stable/security-server.html#_https_support
The Neo4j server includes built in support for SSL encrypted
communication over HTTPS. The first time the server starts, it
automatically generates a self-signed SSL certificate and a private
key. Because the certificate is self signed, it is not safe to rely on
for production use, instead, you should provide your own key and
certificate for the server to use.
In the case that you are using the Neo4j generated self-signed cert and you're still having issues, please update your question with your configuration details in the neo4j-server.properties file for each of your HA instances (if they aren't the same).

Opening SSL TCP socket and sending web requests

I have a requirement to open a tcp socket and authenticate using SSLv3 or TLSv1 IP protocol using X.509 digital certificate.
What does this handshake process involve exactly? I know the each message should be encrypted and signed with my private key. What else?
After successful I've to send POST HTTP requests over the socket.
The server may decide to close this socket if inactive after some time. I need to be able to re-open, authenticate and send requests again.
The certificate given to me is in PKCS12 format with the following information.
Certificate Identification
,Certificate Public Key
,Certificate Private Key
,Certification Authority Chain
I'm fairly new to SSL can someone please provide pointers to how to go about implementing this in java or spring integration.
A good start is to see the javax.net.ssl.HttpsURLConnection javadocs: http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/api/javax/net/ssl/HttpsURLConnection.html
Also you gonna need to use the keytool command to import the certificate into a keystore.
You don't need to know about the handshake, it is all done for you. Read the JSSE Reference as suggested to see what you +do+ have to worry about.
Regarding TLS/SSL details, for client-certificate authentication, compared with the "normal" hanshake, the server sends an extra CertificateRequest TLS message to the client, which responds with its certificate in a subsequent Certificate TLS message (later on, the client sends a CertificateVerify TLS message where it signs the other messages with its private key, so as to prove to the server that it does indeed have the private key for the public key in the certificate it sent.) Note that, once the handshake has finished, the messages are not encrypted with your private key, but with ephemeral keys shared with the server (agreeing on those keys confidentially is part of the handshake too).
In practice, you need a certificate and its private key, contained in the PKCS#12 file (for example) and to configure the client to send it when connecting to the server (the server will ask for it according to its configuration).
It's easier to assume you'll only need one certificate and won't have to make a choice between a number of certificates, otherwise, you need to set up your own X509TrustManager within the SSLContext.
If all your connections are likely to use this certificate, you may use the default settings, which HttpsURLConnection (and the default SSLSocketFactory) will pick up.
This can be done by:
setting the javax.net.ssl.keyStore, javax.net.ssl.keyStoreType and javax.net.ssl.keyStorePassword system properties on the command line with your settings. I would recommend against that because someone else on the machine could potentially see the command line and your settings by listing the processes (depending on the configuration of the machine),
setting those system properties within your application,
initialising an SSLContext and setting it as the default one via SSLContext.setDefault(..) (Java 6).
Note that .p12 (PKCS#12) files are a supported keystore out of the box, so you don't need to do any conversion with keytool, just use PKCS12 as the store type.
If you need these settings or, you may initialise an SSLContext, create an SSLSocketFactory from it and then configure the instance of HttpsURLConnection (if that's what you're using) with setSSLSocketFactory.
(You may be able to use tools like jSSLutils to help build the SSLContext.)

Categories