在Java中的Mqtt客户端SSL例子
我很厌烦连接facebook MQTT服务器(edge-mqtt.facebook.com:443)与ssl,我正在使用Eclipse Paho进行MQTT连接。
private final String DEFAULT_HOST = "edge-mqtt.facebook.com";
private final int DEFAULT_PORT = 443;
public void connect(String protogle) throws Exception {
this.broker = protogle + "://"+ DEFAULT_HOST + ":" + DEFAULT_PORT;
this.mqttClient = new MqttClient(broker,getMqttClientId() ,new MemoryPersistence() );
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setKeepAliveInterval( MQTT_KEEPALIVE);
connOpts.setUserName( getMqttUsername() );
connOpts.setPassword( getMqttPassword().toCharArray() );
connOpts.setMqttVersion( 3 );
//connOpts.setSocketFactory(getSocketFactory (caCrtFile,crtFile,keyFile,password) );
Logger.w("Connecting to broker: "+broker);
Logger.w("isConnected:"+mqttClient.isConnected());
try {
IMqttToken cn = mqttClient.connectWithResult(connOpts);
Logger.w("connected");
}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);
return;
}
this.mqttClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable me) {
Logger.w("Connection lost");
System.out.println("msg "+me.getMessage());
System.out.println("loc "+me.getLocalizedMessage());
System.out.println("cause "+me.getCause());
System.out.println("excep "+me);
}
@Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
Logger.w("message Arrived");
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
Logger.w("deliverd--------");
try {
MqttDeliveryToken token = (MqttDeliveryToken) iMqttDeliveryToken;
String h = token.getMessage().toString();
Logger.w("deliverd message :"+h);
} 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);
} catch (Exception e) {
e.printStackTrace();
}
}
});
public SSLSocketFactory getSocketFactory (final String caCrtFile, final String crtFile, final String keyFile,
final String password) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
// load CA certificate
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
X509Certificate caCert = (X509Certificate)reader.readObject();
reader.close();
// load client certificate
reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
X509Certificate cert = (X509Certificate)reader.readObject();
reader.close();
// load client private key
reader = new PEMReader(
new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
new PasswordFinder() {
@Override
public char[] getPassword() {
return password.toCharArray();
}
}
);
KeyPair key = (KeyPair)reader.readObject();
reader.close();
// CA certificate is used to authenticate server
KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
caKs.load(null, null);
caKs.setCertificateEntry("ca-certificate", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(caKs);
// client key and certificates are sent to server so it can authenticate us
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
ks.setCertificateEntry("certificate", cert);
ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password.toCharArray());
// finally, create SSL socket factory
SSLContext context = SSLContext.getInstance("TLSv1");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
}
我正在寻找如何创建caCrtFile,crtFile和keyFile,并得到了很多答案。 我困惑,现在我不知道哪个答案是真的。 例如,我得到了这个答案。 但我不能实现这一点,所有时间我都有SSL错误。 任何人都可以给我举个例子来为edge-mqtt.facebook.com:443创建这些文件?
如果您尝试进行SSL相互身份验证,则只需要一个crtFile
和keyFile
。 如果是这种情况,那么Facebook会向您发送所需的文件。
caCrtFile
是一个证书链,用于验证Facebook代理在连接到它时提供的证书。 由DigiCert公司颁发的edge-mqtt.facebook.com证书,因此所需的CA证书应该已经包含在Java运行时中。
所有这一切意味着您应该能够使用默认的SSLSocketFactory witoout来添加您自己的信任库或密钥库。
编辑:
因此,删除所有的getSocketFactory()
方法并将其替换为SSLContext.getDefault().getSocketFactory();