有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java通过MQTT和ssl连接安卓设备

我已经用java创建了一个MQTT代理和一个客户机。它也可以使用SSL完美地工作。 由于代理服务器和客户机都是使用paho libs用java编写的,所以启用SSL很容易。我们只需将url中的协议从tcp切换到ssl IE:ssl://.messaging.internetofthings.ibmcloud.com:8883在te src代码中设置一些道具:

java.util.Properties sslClientProps = new java.util.Properties();
sslClientProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
options.setSSLProperties(sslClientProps); 

关于SSLContext

SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);

然后创建一个安全的加密连接(使用WireShark嗅探数据包)

使用特定的CA可信证书也可以很好地工作(messaging.pem文件)

CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream certFile = MqttHandler.class.getResourceAsStream("messaging.pem");
Certificate ca = cf.generateCertificate(certFile);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
TrustManager trustManager = TrustManagerUtils.getDefaultTrustManager(keyStore);
SSLContext sslContext = SSLContextUtils.createSSLContext("TLSv1.2", null, trustManager);
options.setSocketFactory(sslContext.getSocketFactory());

我需要使用Android客户端和定制MQTT Java服务器代理(不使用SSL,MQTT发布和订阅也可以在Android上正常工作)

问题似乎与从Android创建SSLSocketFactory有关

我做了以下测试:

1)设置SSL道具(正如我在上面报告的java客户端的src中所做的那样)

2)在Android客户端上传递CA可信证书(正如我在上面报告的java客户端的src中所做的那样)

3)根据此处报告的BouncyCastle格式(与Android兼容)从受信任CA生成密钥存储http://rijware.com/accessing-a-secure-mqtt-broker-with-安卓/,并在Android客户端上传递密钥存储:

CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream keyStoreFile = getAssets().open("raw_key_file");
//keystore trusted
KeyStore keystoreTrust = KeyStore.getInstance("BKS");//Bouncy Castle format for Android
keystoreTrust.load(keyStoreFile, "mykeystorepassword".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keystoreTrust);
SLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
options.setSocketFactory(sslContext.getSocketFactory());

4)使用本地信任存储(CA)和客户端证书:

// use local trust store (CA)
TrustManagerFactory tmf;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream srvIn = getAssets().open("messaging.pem");
Certificate ca = cf.generateCertificate(srvIn);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
tmf = TrustManagerFactory.getInstance("X509");
tmf.init(keyStore);
// load client certificate
KeyStore clientKeyStore = null;
InputStream clIn = getAssets().open("raw_key_file");
clientKeyStore = KeyStore.getInstance("BKS");
clientKeyStore.load(clIn, "mykeystorepassword".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(clientKeyStore, "mykeystorepassword".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
options.setSocketFactory(sslContext.getSocketFactory());

不幸的是,在所有的测试中,我仍然得到这个错误:MqttException(0)-javax。网ssl。SSLException:对等方关闭连接

MqttException (0) - javax.net.ssl.SSLException: Connection closed by peer
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:604)
at java.lang.Thread.run(Thread.java:841)
Caused by: javax.net.ssl.SSLException: Connection closed by peer
at com.安卓.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.安卓.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:405)
at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:89)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:590)

也许我仍然对证书过程感到困惑。如何从头开始创建并在服务器端和客户端使用(以与Android兼容的BouncyCastle格式创建密钥库)? 或者我在Android中使用SSLSocketFactory类时出错了

谢谢,任何建议都被采纳了


共 (0) 个答案