/
MqttHelper.java
151 lines (124 loc) · 6.15 KB
/
MqttHelper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package helper;
import org.eclipse.paho.client.mqttv3.*;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.security.cert.CertificateFactory;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.io.InputStream;
import java.util.Properties;
public class MqttHelper {
private String brokerHost;
private MqttClient client;
private String username;
private String password;
private String caCertFilePath;
private String clientCertFilePath;
private String clientKeyFilePath;
// MQTTクライアントの作成
public MqttHelper(String clientId) throws MqttException {
// プロパティから設定値を読み込み
String configFile = "config.properties";
Properties properties = new Properties();
try (InputStream inputStream = MqttHelper.class.getClassLoader().getResourceAsStream(configFile)) {
// プロパティファイルを読み込む
properties.load(inputStream);
// プロパティファイルからbrokerのホスト名を取得
this.brokerHost = properties.getProperty("broker.host");
// 設定値の取得
this.username = properties.getProperty("broker.username");
this.password = properties.getProperty("broker.password");
// CA証明書のパス
this.caCertFilePath = properties.getProperty("broker.caCertFilePath");
this.clientCertFilePath = properties.getProperty("broker.clientCertFilePath");
this.clientKeyFilePath = properties.getProperty("broker.clientKeyFilePath");
} catch (Exception e) {
// エラーハンドリング
e.printStackTrace();
throw new MqttException(e);
}
client = new MqttClient(this.brokerHost, clientId);
}
public void connect() throws MqttException {
// 接続オプションの設定
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(false);
// ユーザー名とパスワードがnullでなければ設定する
if (this.username != null && this.password != null) {
connOpts.setUserName(this.username);
connOpts.setPassword(this.password.toCharArray());
}
try {
// SSLContextの作成
SSLSocketFactory sslSocketFactory = createSSLSocketFactory();
connOpts.setSocketFactory(sslSocketFactory);
} catch (Exception e) {
// エラーハンドリング
e.printStackTrace();
throw new MqttException(e);
}
client.connect(connOpts);
System.out.println("Connected to broker");
}
public void publish(String topic, byte[] serializedData) throws MqttException {
MqttMessage mqttMessage = new MqttMessage(serializedData);
client.publish(topic, mqttMessage);
System.out.println("Published message: " + serializedData);
}
public void subscribe(String topic, MqttCallback callback) throws MqttException {
client.setCallback(callback);
client.subscribe(topic);
System.out.println("Subscribed to topic: " + topic);
}
public void disconnect() throws MqttException {
client.disconnect();
System.out.println("Disconnected from broker");
}
private SSLSocketFactory createSSLSocketFactory() throws Exception {
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
// 自己証明書、クライアント証明書/秘密鍵の設定がある場合は、それらを使用してSSLContextを作成
if (this.caCertFilePath != null && this.clientCertFilePath != null && this.clientKeyFilePath != null) {
// CA証明書の読み込み
FileInputStream caCertFile = new FileInputStream(this.caCertFilePath);
Certificate caCert = CertificateFactory.getInstance("X.509").generateCertificate(caCertFile);
caCertFile.close();
// クライアント証明書の読み込み
FileInputStream clientCertFile = new FileInputStream(this.clientCertFilePath);
Certificate clientCert = CertificateFactory.getInstance("X.509").generateCertificate(clientCertFile);
clientCertFile.close();
// クライアント秘密鍵の読み込み
FileInputStream clientKeyFile = new FileInputStream(this.clientKeyFilePath);
byte[] keyBytes = clientKeyFile.readAllBytes();
clientKeyFile.close();
// PKCS#8形式に変換
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// KeyManagerFactoryの作成
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("clientCert", clientCert);
keyStore.setKeyEntry("privateKey", privateKey, null, new Certificate[] { clientCert });
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, null);
// TrustManagerFactoryの作成
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
trustStore.setCertificateEntry("caCert", caCert);
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
} else {
sslContext.init(null, null, null);
}
return sslContext.getSocketFactory();
}
}