10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Paho Java で MQTT ブローカに TLS 接続する

Last updated at Posted at 2016-11-29

今回の例では、mosquittoのテストサーバに接続します。

証明書を取得する

mosquittoの証明書は公開されていので取得します。

$ wget http://test.mosquitto.org/ssl/mosquitto.org.crt

keytool(Java付属の鍵・証明書管理用ツール)で証明書の内容を確認できます。

$ keytool -printcert -file mosquitto.org.crt
keytool -printcert -file mosquitto.org.crt
所有者: EMAILADDRESS=roger@atchoo.org, CN=mosquitto.org, OU=CA, O=Mosquitto, L=Derby, ST=United Kingdom, C=GB
発行者: EMAILADDRESS=roger@atchoo.org, CN=mosquitto.org, OU=CA, O=Mosquitto, L=Derby, ST=United Kingdom, C=GB
シリアル番号: e0fadcf9578c98bc
有効期間の開始日: Sat Jun 30 07:11:59 JST 2012終了日: Tue Jun 28 07:11:59 JST 2022
証明書のフィンガプリント:
	 MD5:  AB:F2:AF:A0:94:9E:08:64:F7:1D:5F:9B:EE:88:D1:8F
	 SHA1: A2:79:92:D3:42:0C:89:F2:93:D3:51:37:8B:A5:F5:67:5F:74:FE:3C
	 SHA256: D1:56:59:4D:32:A9:9D:0C:72:66:5B:5F:94:3C:30:34:D0:7C:DB:A3:60:51:A4:62:56:13:7F:63:1D:2D:F4:E6
	 署名アルゴリズム名: SHA1withRSA
	 バージョン: 3
(省略)

証明書をキーストアにインポートする

Javaで秘密鍵や証明書を扱う場合、キーストアという鍵や証明書を管理するデータベースに入れる必要があります。

$ keytool \
  -import \
  -alias rootCA \
  -trustcacerts \
  -keystore ./crt.jks \
  -storetype jks \
  -storepass testtest \
  -file ./mosquitto.org.crt

ここでは以下を行っています。

  • インポートする証明書としてmosquitto.org.crtを指定。
  • 上記証明書にrootCAというエイリアスをつける。
  • インポート先のキーストア名はcrt.jks
  • キーストアの形式はjks(Java Key Store)
  • キーストアのパスワードはtesttest

以下でキーストアに証明書がインポートされているか確認できます。

$ keytool \
  -list \
  -keystore ./crt.jks \
  -alias rootCA \
  -storepass testtest
rootCA,2016/11/30, trustedCertEntry, 
証明書のフィンガプリント(SHA1): A2:79:92:D3:42:0C:89:F2:93:D3:51:37:8B:A5:F5:67:5F:74:FE:3C

Paho JavaでMQTTS(MQTT over TLS)接続する

通常のTCP接続のサンプルは以下のURLを参照ください。

以下がTLS接続版のサンプルコードです。

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.util.Properties;

public class MqttPublishSample {
    void run () {
        String topic        = "MQTT Examples";
        String content      = "Message from MqttPublishSample";
        int qos             = 2;
        String broker       = "ssl://test.mosquitto.org:8883";
        String clientId     = "JavaSample";
        MemoryPersistence persistence = new MemoryPersistence();
        String trustStore   = this.getClass().getResource("crt.jks").getPath();

        try {
            MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);
            Properties prop = new Properties();
            prop.setProperty("com.ibm.ssl.trustStore", trustStore);
            connOpts.setSSLProperties(prop);
            System.out.println("Connecting to broker: "+broker);
            sampleClient.connect(connOpts);
            System.out.println("Connected");
            System.out.println("Publishing message: "+content);
            MqttMessage message = new MqttMessage(content.getBytes());
            message.setQos(qos);
            sampleClient.publish(topic, message);
            System.out.println("Message published");
            sampleClient.disconnect();
            System.out.println("Disconnected");
            System.exit(0);
        } catch(MqttException me) {
            System.out.println("reason "+me.getReasonCode());
            System.out.println("msg "+me.getMessage());
            System.out.println("loc "+me.getLocalizedMessage());
            System.out.println("cause "+me.getCause());
            System.out.println("excep "+me);
            me.printStackTrace();
        }
    }

    public static void main(String[] args) {
        MqttPublishSample sample = new MqttPublishSample();
        sample.run();
    }
}

TCP接続の場合との違いが2点あります。

1つ目はブローカのURI。

  • スキームとしてsslを指定します。
  • デフォルトポートは8883です(これはブローカの設定によります)。
String broker       = "ssl://test.mosquitto.org:8883";

2つ目はSSL設定を行っていること。

  • Propertiesを作成し、MqttConnectOptions.setSslPropertiesで設定します。
  • 最低限、リモートホストの証明書(あるいは証明書チェーン)を含むキーストアのファイルパスを"com.ibm.ssl.trustStore"で指定します。
    • なお、keytoolでキーストアを扱う場合は完全性の維持のため、パスワードを指定する必要があります。ただし、Java API で扱う証明書を扱う場合はパスワードの指定が不要のようです。
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
Properties prop = new Properties();
prop.setProperty("com.ibm.ssl.trustStore", trustStore);
connOpts.setSSLProperties(prop);

実際に実行するとうまく接続できました。

Connecting to broker: ssl://test.mosquitto.org:8883
Connected
Publishing message: Message from MqttPublishSample
Message published
Disconnected
10
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?