Twinone
Twinone

Reputation: 3029

SSL encryption without validation (SSH Like)

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?

Upvotes: 0

Views: 435

Answers (1)

Bruno
Bruno

Reputation: 122649

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.

Upvotes: 1

Related Questions