X.509 Certificate Based Authentication is used in Two-Way SSL connection. In this case, the certificate itself is the client’s ID, thus, Access Token is no longer needed.
Instructions below will describe how to generate a client-side certificate and connect to the server that is running MQTT over SSL. You will need to have the public key of the server certificate in PEM format. See following instructions for more details on server-side configuration.

Update keygen.properties file

Open the keygen.properties file, and update the values if needed:

  1. DOMAIN_SUFFIX="localhost"
  2. ORGANIZATIONAL_UNIT=ThingsBoard
  3. ORGANIZATION=ThingsBoard
  4. CITY=San Francisco
  5. STATE_OR_PROVINCE=CA
  6. TWO_LETTER_COUNTRY_CODE=US
  7. SERVER_KEYSTORE_PASSWORD=server_ks_password
  8. SERVER_KEY_PASSWORD=server_key_password
  9. SERVER_KEY_ALIAS="serveralias"
  10. SERVER_FILE_PREFIX="mqttserver"
  11. SERVER_KEYSTORE_DIR="/etc/thingsboard/conf/"
  12. CLIENT_KEYSTORE_PASSWORD=password
  13. CLIENT_KEY_PASSWORD=password
  14. CLIENT_KEY_ALIAS="clientalias"
  15. CLIENT_FILE_PREFIX="mqttclient"

Run Client keygen script

Download and launch the client.keygen.sh script.

  1. chmod +x client.keygen.sh
  2. ./client.keygen.sh

The script outputs the following files:

  • CLIENT_FILE_PREFIX.jks - Java Keystore file with the server certificate imported
  • CLIENT_FILE_PREFIX.nopass.pem - Client certificate file in PEM format to be used by non-java client
  • CLIENT_FILE_PREFIX.pub.pem - Client public key

    Provision Client Public Key as Device Credentials

    Go to ThingsBoard Web UI -> Devices -> Your Device -> Device Credentials. Select X.509 Certificate device credentials, insert the contents of CLIENT_FILE_PREFIX.pub.pem file and click save. Alternatively, the same can be done through the REST API.

    Run Two-Way MQTT SSL Python Client

    Download Python client example two-way-ssl-mqtt-client.py.
    Note Script uses 8883 MQTT port and requires paho-mqtt library that you can install using the following command: pip3 install paho-mqtt
    Run the script and follow steps in console:

  • Run command | resources/mqtt-ssl-configuration-run-twowaysslmqttclient.shCopy resources/mqtt-ssl-configuration-run-twowaysslmqttclient.sh to clipboard | | :—- | | ``` python3 two-way-ssl-mqtt-client.py

  1. |
  2. If everything was configured correctly, the output should be like:
  3. - [Result](https://thingsboard.io/docs/user-guide/certificates/#A)
  4. | [`resources/mqtt-ssl-configuration-twowaysslmqttclient-output.txt`](https://raw.githubusercontent.com/thingsboard/thingsboard.github.io/master/docs/user-guide/resources/mqtt-ssl-configuration-twowaysslmqttclient-output.txt)![Copy resources/mqtt-ssl-configuration-twowaysslmqttclient-output.txt to clipboard](https://thingsboard.io/images/copycode.svg "Copy resources/mqtt-ssl-configuration-twowaysslmqttclient-output.txt to clipboard") |
  5. | :--- |
  6. |

Connected with result code 0 Topic: v1/devices/me/attributes/response/1 Message: {}

  1. |
  2. To run Java client, import **CLIENT_FILE_PREFIX.jks** file as follows:
  3. - [MqttSslClient.java](https://thingsboard.io/docs/user-guide/certificates/#A)
  4. | [`resources/MqttSslClient.java`](https://raw.githubusercontent.com/thingsboard/thingsboard.github.io/master/docs/user-guide/resources/MqttSslClient.java)![Copy resources/MqttSslClient.java to clipboard](https://thingsboard.io/images/copycode.svg "Copy resources/MqttSslClient.java to clipboard") |
  5. | :--- |
  6. ```java
  7. import com.google.common.io.Resources;
  8. import org.eclipse.paho.client.mqttv3.*;
  9. import javax.net.ssl.*;
  10. import java.io.File;
  11. import java.io.FileInputStream;
  12. import java.io.FileNotFoundException;
  13. import java.io.IOException;
  14. import java.net.URISyntaxException;
  15. import java.net.URL;
  16. import java.security.*;
  17. import java.security.cert.CertificateException;
  18. public class MqttSslClient {
  19. private static final String MQTT_URL = "ssl://localhost:8883";
  20. private static final String clientId = "MQTT_SSL_JAVA_CLIENT";
  21. private static final String keyStoreFile = "mqttclient.jks";
  22. private static final String JKS="JKS";
  23. private static final String TLS="TLS";
  24. private static final String CLIENT_KEYSTORE_PASSWORD = "password";
  25. private static final String CLIENT_KEY_PASSWORD = "password";
  26. public static void main(String[] args) {
  27. try {
  28. URL ksUrl = Resources.getResource(keyStoreFile);
  29. File ksFile = new File(ksUrl.toURI());
  30. URL tsUrl = Resources.getResource(keyStoreFile);
  31. File tsFile = new File(tsUrl.toURI());
  32. TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
  33. KeyStore trustStore = KeyStore.getInstance(JKS);
  34. trustStore.load(new FileInputStream(tsFile), CLIENT_KEYSTORE_PASSWORD.toCharArray());
  35. tmf.init(trustStore);
  36. KeyStore ks = KeyStore.getInstance(JKS);
  37. ks.load(new FileInputStream(ksFile), CLIENT_KEYSTORE_PASSWORD.toCharArray());
  38. KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
  39. kmf.init(ks, CLIENT_KEY_PASSWORD.toCharArray());
  40. KeyManager[] km = kmf.getKeyManagers();
  41. TrustManager[] tm = tmf.getTrustManagers();
  42. SSLContext sslContext = SSLContext.getInstance(TLS);
  43. sslContext.init(km, tm, null);
  44. MqttConnectOptions options = new MqttConnectOptions();
  45. options.setSocketFactory(sslContext.getSocketFactory());
  46. MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId);
  47. client.connect(options);
  48. Thread.sleep(3000);
  49. MqttMessage message = new MqttMessage();
  50. message.setPayload("{\"key1\":\"value1\", \"key2\":true, \"key3\": 3.0, \"key4\": 4}".getBytes());
  51. client.publish("v1/devices/me/telemetry", message);
  52. client.disconnect();
  53. System.out.println("Disconnected");
  54. System.exit(0);
  55. } catch (Exception e) {
  56. e.printStackTrace();
  57. }
  58. }
  59. }