0

I'm building a network authentication system in java. I want to have my connection encrypted with SSL, so i use SSLServerSocket for it. I've generated a keystore with keytool: (in ssl directory)

keytool -genkey -keystore myKeystore -keyalg RSA

Then in my Server class:

System.setProperty("javax.net.ssl.keyStore", "ssl/myKeystore");
System.setProperty("javax.net.ssl.keyStorePassword", "123456");

Then in my Client:

System.setProperty("javax.net.ssl.trustStore", "ssl/myKeystore");
System.setProperty("javax.net.ssl.trustStorePassword", "123456");

This works, but I can't rely on the client to make a keystore.

My aim is a SSH-like model: The client has a private key which it will send to the server, and the server verifies it using the public key.

Can't I use simple RSA key files instead of keystores?

Twinone
  • 2,949
  • 4
  • 28
  • 39
  • You can't do SSL without certs. You can circumvent the authentication in the initial handshake; but the certs are used for the encryption keys as well. Maybe http://stackoverflow.com/questions/859111/how-do-i-accept-a-self-signed-certificate-with-a-java-httpsurlconnection shows you what you want to do. – Peter Ritchie Feb 24 '13 at 18:59
  • 1
    @PeterRitchie The certificates are not used for encryption. SSL used symmetric session keys generated independently at both ends. – user207421 Feb 24 '13 at 20:24
  • @ejp the key in the cert may be used for encryption... and likely is for some part of the negotiation. And you can't so any SSL (including encryption) without at least on cert. i.e. the peers can't negotiate an encryption algorithm nor exchange new keys without the initial cert. – Peter Ritchie Feb 25 '13 at 02:07
  • 1
    @PeterRitchie The public key in the server cert *may* be used for encryption of a per-master secret by the client, or not, depending on the cipher suite negotiated, and this is not the same thing as 'are used for *the* encryption keys as well'. They aren't. The remainder of your comment was never at issue. – user207421 Feb 25 '13 at 02:38
  • @ejp Semantics, I suppose; I never implied there was a single (e.g. *the*) encryption, just that they were "used for encryption". – Peter Ritchie Feb 25 '13 at 15:24

1 Answers1

1

You seem to be confusing a number of aspects here. Although SSH doesn't rely on SSL/TLS, theses concepts are indeed broadly similar.

What you've done by setting a truststore on your client matching the keystore on the server is making the client trust the server's public key (within its certificate).

This is the SSH equivalent of having pre-loaded trusted server keys fingerprints. Most SSH clients will learn the server's public key or its fingerprint when you establish the first connection (and you're meant to verify this fingerprint manually in principle): you could implement this with SSL/TLS in Java, this is more or less what Andreas Sterbenz's InstallCert does.

The aim of this is to allow the client to verify the server's identity (without which a MITM attack could be possible).

The client has a private key which it will send to the server, and the server verifies it using the public key.

When the client has a private key (which it actually uses, but never sends to the server), it's only used for authenticating the client. The aim of this is to allow the server to verify the client's identity (as an alternative to password authentication, for example).

This can also be done with SSL/TLS using client-certificate authentication.

The main difference (protocol aside) between SSH and SSL/TLS in all this is that SSL/TLS tends to use X.509 certificates (which contain public keys and additional attributes describing the entity's identity), whereas SSH tends to use raw public keys directly. (There are extensions to SSH to use X.509 certificate there too, but they're rather uncommon.)

In both cases, the client will need to verify the server's identity to prevent MITM attacks. This is more conventionally done with SSL/TLS using a Public Key Infrastructure (and X.509 certificates), but you could also learn the key upon first connection, like SSH: this requires more work (you'd need a custom trust manager). A reasonable compromise (in a controlled environment) is to use a trust store on the client, pre-loaded with the server's certificate. This is more or less what you've already done, except that you should never give the server's private key away. You really shouldn't use the same keystore here, since the server's keystore will contain its private key: instead, export only the certificate and import it into a keystore which you'll use as trust store on the other side.

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • I actaully dont care using SSL. Actually, my ideal scenario would be having the server side generate an SSL cert on the first install, and then having the client trust any certificate (the latter I already know how to). I'm not worried about MITM because the first thing the client is requested when he connects is to authenticate, and the connection already is secure. Also I cannot use keytool to generate the certs because my project is to be embedded in devices like Android too, without a full java installation, so I need a way to somehow encrypt the connection or generate the cert at runtime. – Twinone Feb 26 '13 at 17:51
  • "*I'm not worried about MITM because the first thing the client is requested when he connects is to authenticate, and the connection already is secure.*". What secures the connection then? – Bruno Feb 26 '13 at 23:00