3
votes

I am trying to configure a Pre Shared Key encrypted connection between a mosquitto mqtt broker and an application written in Java which uses the Eclipse Paho client library.

I have successfully made connections between the two using no encryption and using SSL where the Server certificate is authenticated but with no client certificate.

I would like to get the connection encrypted (authentication not important) by using a Pre Shared Key, which is definitely supported by the mosquitto broker, but I am uncertain whether the Eclipse Paho library supports it or not.

The library offers you two different ways of configuring a secure connection. Either through the

setSSLProperties(java.util.Properties props)

method - making use of the following properties:

com.ibm.ssl.protocol
com.ibm.ssl.contextProvider
com.ibm.ssl.keyStore
com.ibm.ssl.keyStorePassword
com.ibm.micro.security.Password.obfuscate(char[] password). 
com.ibm.ssl.keyStoreType
com.ibm.ssl.keyStoreProvider
com.ibm.ssl.trustStore
com.ibm.ssl.trustStorePassword
com.ibm.micro.security.Password.obfuscate(char[] password).
com.ibm.ssl.trustStoreType
com.ibm.ssl.trustStoreProvider
com.ibm.ssl.enabledCipherSuites
com.ibm.ssl.keyManager
com.ibm.ssl.trustManager

or through the

setSocketFactory(javax.net.SocketFactory socketFactory)

method.

Does anyone have any experience with the tools and libraries that I am using and could anyone offer any suggestions as to how I might be able to get something working?

Is it possible to create an ssl socket factory which is capable of returning a socket that can cope with the PSK implementation I will need?

Thanks for your help :-)

3

3 Answers

2
votes

The Paho client relies on whatever security cyphers etc are provided within the JVM runtime; Paho does not provide any itself.

As far as I know, none of the mainstream JVM providers include TLS-PSK support. It may be possible to add support from a third party, such as http://www.bouncycastle.org/

You may also want to check these (currently unanswered) quesitons on this subject:

1
votes

My bet is that the Paho clients don't support TLS PSK out of the box. TLS-PSK support is only relatively new in openssl for example, so it's not too surprising that it isn't widely supported. It isn't supported in Python for example.

The only MQTT clients that I know support TLS-PSK are those based on the mosquitto C/C++ libraries such as mosquitto_pub/mosquitto_sub.

You might be better directing your question to the Paho mailing list.

1
votes

Yes, it is possible to pass the paho mqtt client a SocketFactory that does TLS-PSK using bouncy castle. It is not so pretty, though (maybe someone has a better solution?).

My answer is based on this example: http://tiebing.blogspot.de/2013/09/java-bouncy-castle-tls-psk-example.html From there You take the inner classes Z_PSKIdentity and MyPSKTlsClient.

Then You need a SocketFactory like this:

class PskSocketFactory extends SSLSocketFactory {

    public Socket createSocket() {
        SSLSocket mySocket = new SSLSocket() {
            TlsClientProtocol protocol = null;

            @Override
            public void startHandshake() throws IOException {
                try {
                    protocol = new TlsClientProtocol(super.getInputStream(), super.getOutputStream(), new SecureRandom());
                } catch (Exception e) {
                    e.printStackTrace();
                }

                Z_PSKIdentity pskIdentity = new Z_PSKIdentity();
                MyPSKTlsClient client = new MyPSKTlsClient(pskIdentity);
                protocol.connect(client);
            }

            @Override
            public InputStream getInputStream() throws IOException {
                return protocol.getInputStream();
            }

            @Override
            public OutputStream getOutputStream() throws IOException {
                return protocol.getOutputStream();
            }

            return mySocket;
        }
    }

}

There are a lot of abstract methods in SSLSocketFactory as well as SSLSocket. You need to implement them but they are not used, as far as I know, so You can let Your IDE generate them with nonsense-bodies. I have left them out of the code for readability.

I don't know about mosquitto, but this method worked for me with a clear-text HiveMQ behind stunnel as TLS-proxy.

If You need to change/select the cipher then just override getCipherSuites in MyPSKTlsClient like this:

public int[] getCipherSuites() {
    return new int[] { CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA };
}