How can I securely authenticate to a server socket with java? - java

I have written a java program, where a client connects to a server via socket (not SSLSocket!).
First the client creates an RSA-keypair and then sends the public key to the server. Then the server responds with a public key, which the client uses to create the RSA-encoded login password for authentication.
Is this a safe way or, if not, how can I ensure the security of the password?

You would almost never implement a handshake protocol yourself unless you were an expert in cryptography.
Instead, since I can presume you're using a protocol like TCP, UDP, or HTTP, you can use libraries like Netty or just the built in TLS/SSL support.
Netty SSL Example
SSLSocket (i know you said you didnt use it) class for no 3rd party usage.

Related

Jetty client / server mutual authentication

I am trying to build a client / server servlet application with these general requisites:
both the client and the server are jetty embedded;
the server expose a servlet in order to receive json data via POST;
the connection must be secured via SSL (i.e. the connection will be done via Internet via https);
I want that only my Jetty client be able to send data to my server, all other tentative must be refused by the server;
the server and the client are unattended machines (i.e. not password via command line could be inserted by human);
no password in clear must be stored on the client device. In general I don't want someone could open the remote client device and stole the password and building a fake remote device capable to send data to my server too.
I have build a perfectly working client / server application via HTTP but I am confused about the security.
I have read that there is the possibility to use client / server mutual authentication and seems what I am looking for but I can't get the complete picture.
In this document client-certificate-authentication there is a more or less clear explanation about how to build a shared trusted CA but the password for accessing the TrustStore and the KeyStore are in clear in the code.
I think I am missing a tile in the puzzle.
Could someone point me in the right direction?
Thanks,
S.
I'm going with a simple answer (for now).
If you just want only your clients to talk to the server, then yes, Client SSL/TLS certificates are the way to go.
You'll want the server's SslContextFactory.Server.setNeedClientAuth(true) set to true. That will in turn cause Java's javax.net.ssl.SSLParameters.setNeedClientAuth(true) to be set on incoming connection establishment. If the client fails to provide the client certificate, the connection is closed, and no HTTP request is sent or processed.
As for securing the client certificate, that's up to you, you can do anything you want to do, as long as it results in a valid client SslContextFactory.Client that the Jetty client can access. This includes ...
Using plaintext passwords
Using obfuscated passwords (minimal effort, minimal security)
Encrypted keystore/truststore passwords elsewhere in your client, provided to the SslContextFactory.Client at the last minute. (modest security, wouldn't be that hard to figure out)
Creating the java.security.KeyStore object yourself and handing it to SslContextFactory.Client.setKeyStore(KeyStore) and SslContextFactory.Client.setTrustStore(KeyStore) methods prior to starting the Jetty Client. (a bit better security wise, puts more work on your behalf)
You might want to consider having the client certificates be short-lived (24 hours?) dynamically refreshed from the server, and have the client certificates be revokable (at the server/CA side) if you encounter abuse. (such as the same client certificate from multiple different client IPs)

Writing a secure RMI server-client application

I'm writing a server-client application where communication is done over the internet and I have several questions and concerns regarding security. I have done some research and found some posts here useful, but I would like more information. Some related questions I read were:
Secure authentication of client over RMI
java rmi authentication & security. exportObject makes it public?
Is communication in java rmi secure?
I have 3 parts to consider:
Information exchanged between the client and the server.
Authentication of the client.
Exploiting a running RMI server (hacking etc.).
What I know:
RMI over SSL. Using SSL sockets instead of the default socket would encrypt all information passed between the client and the server. This includes the objects exchange and method calls.
Authentication using username/password combination over SSL before RMI connection has been established. To my understanding there was supposed to be a way to authenticate inside the RMI connection but it was voted down.
Not too sure what can or needs to be done here. I do know that you can't just write your own client and ask to connect to the server since you need an ObjectID and the remote interfaces. However, is it not possible to decompile the classes \ interfaces you need since they are sent in RMI anyway? I also saw this Youtube video [http://www.youtube.com/watch?v=otjllNaBxiw] while researching and it got me worried with how easy it is, although I don't know if the server was not setup correctly.
All in all, are there other security issues I need to consider in RMI over the internet? Am I missing a solution I need to look at? Is what I already know wrong?
Information exchanged between the client and the server.
RMI over SSL.
Authentication of the client.
Authentication of the client is done by SSL. You mean authorisation, which is 'relatively' easy. Define your own RMIServerSocketFactory that returns an ServerSocket override whose implAccept() method wraps the socket in an SSLSocket, to which you add a handshake listener and set needClientAuth to true on it (and clientMode to false). Your handshake listener should then get and check the client certificate from the SSLSession, to see if the identity it authenticates is authorised, and simply close the socket if non-authorised.
Authorising the server, in the client, is on the other hand baroquely complex. You really need the JERI API in Jini to do it properly.
Exploiting a running RMI server (hacking etc.).
I won't go so far as to say it's impossible, but it's extremely difficult, and there are several strong lines of defence. You need the ObjectID, which is random, and can be made securely random, and you need the classes. Classes and interfaces aren't sent in RMI unless you specifically enable it, and they are sent by a side channel that you can secure arbitrarily strongly, for example with two-way-authenticated HTTPS. So you can't get those. Then you need to get yourself authorised, which basically requires compromising the server. And if that's possible, anything is.

How to secure communication in client-server app?

I've got backend running on the tomcat server and client running in the browser. Application is built on Spring 3 MVC + Spring security framework. How to secure the communication ? Is there other option than just to set the server to be accessed only via HTTPS ? I've got no experience with this so it might be a stupid question, but will this affect my application and do I have to set something up in my app, when the server shall communicate with client via GET/POST request via https ?
It depends somewhat what you mean by "secure." If you want privacy, you must use TLS (SSL) as a transport.
If you're only concerned with authentication, then you have another option: Digest Authentication.
Digest Authentication allows the client (browser, usually) and the server to exchange authentication credentials in a secure manner without securing the entire communication. If you use Digest Authentication, then third parties can still:
See what data the client and server exchange
Insert themselves between the client and server and alter the exchange
What third parties cannot do is spoof the authentication or steal username/passwords in transit.
If that's not secure enough, you need TLS. You do not necessarily have to purchase a certificate. You can use OpenSSL to generate your own. This certificate will not automatically be trusted by browsers, however, so you can't really use it for public sites.
You will need to consult your server documentation for how to set up HTTPS or Digest Authentication, depending on which fits your needs.
Your application should not be affected by switching from HTTP to HTTPS, Tomcat handles this or maybe an Apache in front. It's important to understand, that HTTPS is a server-thing, not an application topic, because the client makes a connection to the server (Tomcat), not to your application. Check out the Tomcat documentation, it's pretty clear about how things work.
And, like the others said: From what you've said it's best to use HTTPS (TLS/SSL). Certificates are a bit frightning at the beginning, but it's worth to invest the time.
HTTPS is the (S)ecure form of HTTP, since you have an HTTP client server application I would certainly used HTTPS. All you need is to create an SSL certicate for your website and restrict access to your website to HTTPS only, then you are 99.99% secure.
Your certicate can be either commercial from Versign or equivalent or some open source engine.
for the clients nothing needs to be done to support HTTPS

Is there a java tls server implementation that is transport agnostic?

I'm trying to tunnel tls via a text-only communication channel (I thought about using base64) but I cannot seem to find a tls server example that doesn't use SSLSocket.
For a tls client I was able to find the bouncy castle TlsProtocolHandler which is transport agnostic because it just uses an input and output stream, but I couldn't find anything similar for a server tls implementation.
Using SSLSocket:
You can certainly implement your own Socket that is not based on TCP. For example there are Unix socket implementations. Once you have it for your own transport, SSLSocketFactory.createSocket(Socket, ...) can establish an SSLSocket on top of your own Socket.
Using SSLEngine (a bit more complex):
SSLEngine.wrap (and unwrap) work on ByteBuffers. These buffers could come from your own communication channel.
One of the difficulties you may encounter is the mapping of the notion of certificates to your custom transport. Certificates (or more generally proving the identity of the server) is essential to the security of an SSL/TLS channel, to prevent MITM attacks. Identity verification requires both checking the certificate as trusted, and that the identity it's for corresponds to the entity you were trying to reach (hostname verification). Hostname verification isn't enabled by default, but you'd need to find something similar anyway, if you don't have host names (that could be a problem for unix sockets, for example, although using SSL in this case might not make sense anyway).

SSO .NET thick client with Java server via TCP using Kerberos

I intend to have .NET thick clients running inside a Windows domain connect to a Java server via a straight TCP connection (protocol will be custom Google Protocol Buffer messages). I'm looking at how I can authenticate these clients without requiring further credentials be entered by the users (in other words, support single sign-on).
My initial thinking was to use Kerberos, but I'm not even certain that it's possible or ultimately secure over straight TCP. Can anyone comment on this? Is it possible? Are there any examples out there of how to achieve this, both client-side and server-side?
Kerberos doesn't run over 'straight TCP'. It uses an encryption protocol. See the JGSS-API, built into the JRE.

Categories

Resources