+

Search Tips | Advanced Search

TLS configuration of MQTT Java clients and telemetry channels

Configure TLS to authenticate the telemetry channel and the MQTT Java client, and encrypt the transfer of messages between them. MQTT Java clients use Java Secure Socket Extension (JSSE) to connect telemetry channels using TLS. As an alternative to using SSL, some kinds of Virtual Private Network (VPN), such as IPsec, authenticate the endpoints of a TCP/IP connection. VPN encrypts each IP packet that flows over the network. Once such a VPN connection is established, we have established a trusted network. We can connect MQTT clients to telemetry channels using TCP/IP over the VPN network.

We can configure the connection between a Java MQTT client and a telemetry channel to use the TLS protocol over TCP/IP. What is secured depends on how you configure TLS to use JSSE. Starting with the most secured configuration, we can configure three different levels of security:

  1. Permit only trusted MQTT clients to connect. Connect an MQTT client only to a trusted telemetry channel. Encrypt messages between the client and the queue manager; see MQTT client authentication using TLS
  2. Connect an MQTT client only to a trusted telemetry channel. Encrypt messages between the client and the queue manager; see Telemetry channel authentication using TLS.
  3. Encrypt messages between the client and the queue manager; see Publication privacy on telemetry channels.


JSSE configuration parameters

Modify JSSE parameters to alter the way an TLS connection is configured. The JSSE configuration parameters are arranged into three sets:

  1. MQ Telemetry channel
  2. MQTT Java client
  3. JRE

Configure the telemetry channel parameters using IBM MQ Explorer. Set the MQTT Java Client parameters in the MqttConnectionOptions.SSLProperties attribute. Modify JRE security parameters by editing files in the JRE security directory on both the client and server.


Modify the trust provider to permit the client to connect to any server

The example illustrates how to add a trust provider and reference it from the MQTT client code. The example performs no authentication of the client or server. The resulting TLS connection is encrypted without being authenticated.

The code snippet in Figure 1 sets the AcceptAllProviders trust provider and trust manager for the MQTT client.

Figure 1. MQTT Client code snippet
java.security.Security.addProvider(new AcceptAllProvider());
java.util.Properties sslClientProperties = new Properties();
sslClientProperties.setProperty("com.ibm.ssl.trustManager","TrustAllCertificates");
sslClientProperties.setProperty("com.ibm.ssl.trustStoreProvider","AcceptAllProvider");
conOptions.setSSLProperties(sslClientProperties);
Figure 2. AcceptAllProvider.java
package com.ibm.mq.id;
public class AcceptAllProvider extends java.security.Provider {
private static final long serialVersionUID = 1L;
public AcceptAllProvider() {
super("AcceptAllProvider", 1.0, "Trust all X509 certificates");
put("TrustManagerFactory.TrustAllCertificates",
AcceptAllTrustManagerFactory.class.getName());
}
Figure 3. AcceptAllTrustManagerFactory.java
protected static class AcceptAllTrustManagerFactory extends
javax.net.ssl.TrustManagerFactorySpi {
public AcceptAllTrustManagerFactory() {}
protected void engineInit(java.security.KeyStore keystore) {}
protected void engineInit(
javax.net.ssl.ManagerFactoryParameters parameters) {}
protected javax.net.ssl.TrustManager[] engineGetTrustManagers() {
return new javax.net.ssl.TrustManager[] { new AcceptAllX509TrustManager() };
}
Figure 4. AcceptAllX509TrustManager.java
protected static class AcceptAllX509TrustManager implements
javax.net.ssl.X509TrustManager {
public void checkClientTrusted(
java.security.cert.X509Certificate[] certificateChain,
String authType) throws java.security.cert.CertificateException {
report("Client authtype=" + authType);
for (java.security.cert.X509Certificate certificate : certificateChain) {
report("Accepting:" + certificate);
}
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certificateChain,
String authType) throws java.security.cert.CertificateException {
report("Server authtype=" + authType);
for (java.security.cert.X509Certificate certificate : certificateChain) {
report("Accepting:" + certificate);
}
}
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
private static void report(String string) {
System.out.println(string);
}
}