Skip to content

Commit 2741937

Browse files
authored
feat(java): add one way tls/ssl sample (emqx#100)
1 parent c4cc373 commit 2741937

File tree

5 files changed

+154
-1
lines changed

5 files changed

+154
-1
lines changed

mqtt-client-Java/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
mvn compile
99
```
1010

11+
## Run one way TLS authentication sample
12+
13+
```bash
14+
mvn exec:java -Dexec.mainClass="io.emqx.mqtt.MqttOneWayTlsSample"
15+
```
16+
1117
## Run two way TLS authentication sample
1218

1319
```bash

mqtt-client-Java/README_ZH.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
mvn compile
99
```
1010

11+
## 运行单向 TLS 认证示例
12+
13+
```bash
14+
mvn exec:java -Dexec.mainClass="io.emqx.mqtt.MqttOneWayTlsSample"
15+
```
16+
1117
## 运行双向 TLS 认证示例
1218

1319
```bash
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package io.emqx.mqtt;
2+
3+
import org.eclipse.paho.client.mqttv3.*;
4+
5+
import javax.net.ssl.SSLContext;
6+
import javax.net.ssl.SSLSocketFactory;
7+
import javax.net.ssl.TrustManagerFactory;
8+
import java.io.FileInputStream;
9+
import java.security.*;
10+
import java.security.cert.Certificate;
11+
import java.security.cert.CertificateFactory;
12+
import java.security.cert.X509Certificate;
13+
import java.text.MessageFormat;
14+
import java.util.Arrays;
15+
16+
public class MqttOneWayTlsSample {
17+
private static final String BROKER = "broker.emqx.io";
18+
private static final String PORT = "8883";
19+
private static final String CLIENT_ID = MqttClient.generateClientId();
20+
private static final String USERNAME = "emqx";
21+
private static final String PASSWORD = "public";
22+
private static final int CONNECT_TIMEOUT = 300;
23+
private static final boolean CLEAN_SESSION = true;
24+
private static final String TOPIC = "java-mqtt/tls";
25+
private static final int QoS = 1;
26+
private static final String PAYLOAD = "Enjoy the sample";
27+
private static final String CA_CERT_PATH = MqttOneWayTlsSample.class.getResource("").getPath()+"./broker.emqx.io-ca.crt";
28+
29+
public static void main(String args[]) {
30+
MqttClient client = null;
31+
try {
32+
String server = "ssl://" + BROKER + ":" + PORT;
33+
client = new MqttClient(server, CLIENT_ID);
34+
35+
client.setCallback(new MqttCallback() {
36+
37+
@Override
38+
public void connectionLost(Throwable cause) {
39+
System.out.println(MessageFormat.format("Connection lost. Cause: {0}", cause));
40+
}
41+
42+
@Override
43+
public void messageArrived(String topic, MqttMessage message) throws Exception {
44+
System.out.println(MessageFormat.format("Callback: received message from topic {0}: {1}",
45+
topic, message.toString()));
46+
}
47+
48+
@Override
49+
public void deliveryComplete(IMqttDeliveryToken token) {
50+
try {
51+
System.out.println(MessageFormat.format("Callback: delivered message to topics {0}",
52+
Arrays.asList(token.getTopics())));
53+
} catch (Exception e) {
54+
e.printStackTrace();
55+
}
56+
}
57+
58+
});
59+
60+
MqttConnectOptions options = new MqttConnectOptions();
61+
options.setUserName(USERNAME);
62+
options.setPassword(PASSWORD.toCharArray());
63+
options.setConnectionTimeout(CONNECT_TIMEOUT);
64+
options.setCleanSession(CLEAN_SESSION);
65+
options.setSocketFactory(getSocketFactory(CA_CERT_PATH));
66+
67+
System.out.println("Connecting to broker: " + server);
68+
client.connect(options);
69+
70+
if (!client.isConnected()) {
71+
System.out.println("Failed to connect to broker: " + server);
72+
return;
73+
}
74+
System.out.println("Connected to broker: " + server);
75+
76+
client.subscribe(TOPIC, QoS);
77+
System.out.println("Subscribed to topic: " + TOPIC);
78+
79+
MqttMessage msg = new MqttMessage(PAYLOAD.getBytes("UTF-8"));
80+
msg.setQos(QoS);
81+
client.publish(TOPIC, msg);
82+
83+
System.out.println("Disconnect from broker: " + server);
84+
client.disconnect();
85+
} catch (Exception ex) {
86+
ex.printStackTrace();
87+
} finally {
88+
if (client != null) {
89+
try {
90+
client.close();
91+
} catch (MqttException e) {
92+
e.printStackTrace();
93+
}
94+
}
95+
}
96+
}
97+
98+
public static SSLSocketFactory getSocketFactory(String caCertPath) throws Exception {
99+
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
100+
101+
// load CA certificate into keystore to authenticate server
102+
Certificate caCert = certFactory.generateCertificate(new FileInputStream(caCertPath));
103+
X509Certificate x509CaCert = (X509Certificate) caCert;
104+
105+
KeyStore caKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
106+
caKeyStore.load(null, null);
107+
caKeyStore.setCertificateEntry("cacert", x509CaCert);
108+
109+
TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
110+
tmFactory.init(caKeyStore);
111+
112+
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
113+
sslContext.init(null, tmFactory.getTrustManagers(), null);
114+
115+
return sslContext.getSocketFactory();
116+
}
117+
}

mqtt-client-Java/src/main/java/io/emqx/mqtt/SSLUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
public class SSLUtils {
2121

22-
public static SSLSocketFactory getSingleSocketFactory(InputStream caCrtFileInputStream) throws Exception {
22+
public static SSLSocketFactory getSingleSocketFactory(final String caCrtFile) throws Exception {
2323
Security.addProvider(new BouncyCastleProvider());
2424
X509Certificate caCert = null;
2525

26+
FileInputStream caCrtFileInputStream = new FileInputStream(caCrtFile);
27+
2628
BufferedInputStream bis = new BufferedInputStream(caCrtFileInputStream);
2729
CertificateFactory cf = CertificateFactory.getInstance("X.509");
2830

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
3+
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
4+
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
5+
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
6+
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
7+
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
8+
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
9+
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
10+
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
11+
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
12+
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
13+
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
14+
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
15+
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
16+
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
17+
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
18+
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
19+
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
20+
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
21+
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
22+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)