Мне удалось установить MQTT-соединение с брокером без сертификата TLS / SSL с использованием службы paho {mqttv3: 1.1.0}.Однако, когда я попытался закрепить SSL-сертификат в Android, он не работал.Пожалуйста, помогите мне в решении проблемы.Прикрепление кода для получения дополнительной информации.
Шаг 1: Преобразование сертификата
Преобразованный файл certificate.pem в формат надувного замка и хранится в необработанной папке в проекте Android.
D:\>"C:\Program Files\Java\jdk1.8.0_121\bin\keytool" -import -alias mqtt-broker -file C:\Users\abcd\Downloads\certificate.pem -keypass ***** -keystore raw_key_file -storetype BKS -storepass ***** -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath C:\Users\abcd\Downloads\bcprov-jdk16-1.45.jar
Шаг 2: Настройки клиента MQTT
mclientPublisher = new MqttAndroidClient(context, mqttBrokerURL,PublisherClientID, new MemoryPersistence());
if (null != mclientPublisher)
{
MqttConnectOptions options = null;
options = new MqttConnectOptions();
options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
options.setConnectionTimeout(60);
options.setKeepAliveInterval(120);
options.setAutomaticReconnect(true);
SslUtility.newInstance(context);
options.setSocketFactory(SslUtility.getInstance().getSocketFactory
(R.raw.raw_key_file,"****"));
options.setCleanSession(true);
}
Шаг 3: КЛАСС УТИЛИТЫ SSL
public class SslUtility {
private static SslUtility mInstance = null;
private Context mContext = null;
private HashMap<Integer, SSLSocketFactory> mSocketFactoryMap = new
HashMap<Integer, SSLSocketFactory>();
public SslUtility(Context context) {
mContext = context;
}
public static SslUtility getInstance( ) {
if ( null == mInstance ) {
throw new RuntimeException("the first call must be to
SslUtility.newInstance(Context) ");
}
return mInstance;
}
public static SslUtility newInstance( Context context ) {
if ( null == mInstance ) {
mInstance = new SslUtility( context );
}
return mInstance;
}
public SSLSocketFactory getSocketFactory(int certificateId, String
certificatePassword )
{
SSLSocketFactory result = mSocketFactoryMap.get(certificateId);
if ( ( null == result) && ( null != mContext ) ) {
try {
KeyStore keystoreTrust = KeyStore.getInstance("BKS");
keystoreTrust.load(mContext.getResources().
openRawResource(certificateId),certificatePassword.toCharArray());
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory
.getDefaultAlgorithm());
trustManagerFactory.init(keystoreTrust);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(),
new SecureRandom());
result = sslContext.getSocketFactory();
mSocketFactoryMap.put( certificateId, result);
}
catch ( Exception ex ) {
}
}
return result;
}
ОШИБКА / LOGCAT:
05-18 10:18:55.638 20810-20810/: disconnect method -inside catch block- Error is : java.lang.NullPointerException: Attempt to invoke virtual method 'boolean org.eclipse.paho.android.service.MqttAndroidClient.isConnected()' on a null object reference
Кажется, объект клиента MQTT не создан.
Ссылка:
Закрепление SSL-сертификата в библиотеке Android-MQTT [Paho]
Paho-eclipse-Forum
Разработчики Android-Google
HiveMQ-Mqtt