在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相互身份验证,则只需要一个crtFilekeyFile 。 如果是这种情况,那么Facebook会向您发送所需的文件。

caCrtFile是一个证书链,用于验证Facebook代理在连接到它时提供的证书。 由DigiCert公司颁发的edge-mqtt.facebook.com证书,因此所需的CA证书应该已经包含在Java运行时中。

所有这一切意味着您应该能够使用默认的SSLSocketFactory witoout来添加您自己的信任库或密钥库。

编辑:

因此,删除所有的getSocketFactory()方法并将其替换为SSLContext.getDefault().getSocketFactory();

链接地址: http://www.djcxy.com/p/31149.html

上一篇: Mqtt client ssl example in java

下一篇: how to play .opus audio file in android?