mqtt paho ssl java端代码【转】

来自:http://blog.csdn.net/lingshi210/article/details/52439050

mqtt ssl配置可以参阅 
http://houjixin.blog.163.com/blog/static/35628410201432205042955/

然后注意开启防火墙端口。

mqtt的命令和Java端的ssl 必须同时要带上ca.crtclilent.crtclient.key三个文件,即CA证书、客户证书、客户私钥。

由于java 端不支持client.key的格式,需要命令进行转化

openssl pkcs8 -topk8 -in client.key -out client.pem -nocrypt

另外: 
不知为何ubuntu下关闭防火墙后还是握手失败,cenos下正常,抓包后已经看不到明文了。

Java部分:

1.核心部分只需要设置SSLSocketFactory

MqttConnectOptions options = new MqttConnectOptions();
SSLSocketFactory factory=getSSLSocktet("youpath/ca.crt","youpath/client.crt","youpath/client.pem","password");
 
options.setSocketFactory(factory);

2.自定义SSLSocketFactory (改进于http://gist.github.com/4104301

此处的密码应为生成证书的时候输入的密码,未认证。

private SSLSocketFactory getSSLSocktet(StringcaPath,String crtPath, String keyPath, String password) throws Exception {
        // CAcertificate is used to authenticate server
       CertificateFactory cAf = CertificateFactory.getInstance("X.509");
       FileInputStream caIn = new FileInputStream(caPath);
       X509Certificate ca = (X509Certificate) cAf.generateCertificate(caIn);
         KeyStorecaKs = KeyStore.getInstance("JKS");
         caKs.load(null, null);
         caKs.setCertificateEntry("ca-certificate", ca);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
         tmf.init(caKs);
 
       CertificateFactory cf = CertificateFactory.getInstance("X.509");
        FileInputStreamcrtIn = new FileInputStream(crtPath);
       X509Certificate caCert = (X509Certificate) cf.generateCertificate(crtIn);
 
        crtIn.close();
        // clientkey and certificatesare sent to server so it can authenticate
        // us
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
//      ks.load(caIn,password.toCharArray());
        ks.load(null, null);
        ks.setCertificateEntry("certificate", caCert);
        ks.setKeyEntry("private-key",getPrivateKey(keyPath), password.toCharArray(),
                newjava.security.cert.Certificate[]{caCert}  );
       KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
        kmf.init(ks, password.toCharArray());
//      keyIn.close();
 
        // finally,create SSL socket factory
        SSLContextcontext = SSLContext.getInstance("TLSv1");
 
        context.init(kmf.getKeyManagers(),tmf.getTrustManagers(), newSecureRandom());
 
        returncontext.getSocketFactory();
    }

Android上会报错,改进如下:

 

   privateSSLSocketFactory getSSLSocktet(String caPath,String crtPath, String keyPath,String password) throws Exception {
        // CAcertificate is used to authenticate server
       CertificateFactory cAf = CertificateFactory.getInstance("X.509");
       FileInputStream caIn = new FileInputStream(caPath);
       X509Certificate ca = (X509Certificate) cAf.generateCertificate(caIn);
         KeyStorecaKs = KeyStore.getInstance(KeyStore.getDefaultType());
         caKs.load(null, null);
         caKs.setCertificateEntry("ca-certificate", ca);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
         tmf.init(caKs);
         caIn.close();
       CertificateFactory cf = CertificateFactory.getInstance("X.509");
       FileInputStream crtIn = new FileInputStream(crtPath);
        X509CertificatecaCert = (X509Certificate) cf.generateCertificate(crtIn);
 
        crtIn.close();
        // clientkey and certificatesare sent to server so it can authenticate
        // us
        KeyStore ks= KeyStore.getInstance(KeyStore.getDefaultType());
//      ks.load(caIn,password.toCharArray());
        ks.load(null, null);
        ks.setCertificateEntry("certificate", caCert);
        ks.setKeyEntry("private-key",getPrivateKey(keyPath), password.toCharArray(),
                newjava.security.cert.Certificate[]{caCert}  );
       KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, password.toCharArray());
//      keyIn.close();
 
        // finally,create SSL socket factory
        SSLContext context = SSLContext.getInstance("TLSv1");
 
        context.init(kmf.getKeyManagers(),tmf.getTrustManagers(), newSecureRandom());
 
        returncontext.getSocketFactory();
    }

3.获取私钥代码部分

由于只能读取PKCS8的格式,所以需要转成pem

   

 public PrivateKey getPrivateKey(String path) throws Exception{ 
 
 
 
       org.apache.commons.codec.binary.Base64 base64=new Base64();
        byte[] buffer=   base64.decode(getPem(path));
 
       PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);
        KeyFactorykeyFactory= KeyFactory.getInstance("RSA"); 
        return (RSAPrivateKey)keyFactory.generatePrivate(keySpec); 

    }

附录:

package com;
 
importjava.awt.BorderLayout;
importjava.awt.Container;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.io.BufferedReader;
importjava.io.FileInputStream;
import java.io.InputStream;
importjava.io.InputStreamReader;
importjava.security.KeyFactory;
importjava.security.KeyStore;
importjava.security.PrivateKey;
importjava.security.SecureRandom;
importjava.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
importjava.security.cert.X509Certificate;
importjava.security.interfaces.RSAPrivateKey;
importjava.security.spec.PKCS8EncodedKeySpec;
 
importjavax.net.ssl.KeyManagerFactory;
importjavax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
importjavax.net.ssl.TrustManager;
importjavax.net.ssl.TrustManagerFactory;
importjavax.net.ssl.X509TrustManager;
importjavax.swing.JButton;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JOptionPane;
import javax.swing.JPanel;
importjavax.swing.JTextArea;
 
importorg.apache.commons.codec.binary.Base64;
importorg.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
importorg.eclipse.paho.client.mqttv3.MqttCallback;
importorg.eclipse.paho.client.mqttv3.MqttClient;
importorg.eclipse.paho.client.mqttv3.MqttConnectOptions;
importorg.eclipse.paho.client.mqttv3.MqttMessage;
importorg.eclipse.paho.client.mqttv3.MqttTopic;
importorg.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
 
publicclassServerextendsJFrame {
    privatestaticfinallongserialVersionUID = 1L;
    private JPanel panel;
    private JPanelpanelText;
    private JPanelpanelText2;
    private JButton button;
    private JButtonbutton2;
    private JButtonsubscribeButton;
    private JTextAreatextHost;
    private JTextAreatextClientID;
    private JTextAreatextPublishMsg;
    private JTextAreatextTopic;
 
    private MqttClientclient;
    private String host = "ssl://192.168.10.233:1883";
 
    private MqttTopictopic;
    private MqttMessagemessage;
 
    private StringuserToken = "999999";
 
    private StringmyTopicRoot = "test";
    private String myTopic= null;
 
    private String clienID= "test1234567";
 
    publicServer() {
 
        Containercontainer = this.getContentPane();
        panel = new JPanel();
        panelText =new JPanel();
        panelText2= new JPanel();
        button = new JButton("发布主题消息");
        button2 = new JButton("更换客户机地址和IP");
       button.addActionListener(new ActionListener() {
 
            @Override
            publicvoidactionPerformed(ActionEvent ae){
                try {
                   host = textHost.getText();
                   clienID = textClientID.getText();
                   if (client == null) {
                       client = newMqttClient(host, clienID, new MemoryPersistence());
                   }
 
                   if(!client.isConnected()) {
                       connect();
                   }
 
                   publishMsg(textTopic.getText(), textPublishMsg.getText());
                } catch (Exception e) {
                   e.printStackTrace();
                   showErrorMsg(e.toString());
                }
            }
        });
 
       button2.addActionListener(new ActionListener() {
 
            @Override
            publicvoidactionPerformed(ActionEventarg0) {
                // TODO Auto-generated method stub
               host = textHost.getText();
               clienID = textClientID.getText();
                try {
                   if (client != null)
                       client.disconnectForcibly();
                   client = newMqttClient(host, clienID, new MemoryPersistence());
                   connect();
                } catch (Exception e) {
                   e.printStackTrace();
                   showErrorMsg(e.toString());
                }
            }
        });
 
       subscribeButton = new JButton("订阅主题");
        subscribeButton.addActionListener(newActionListener() {
 
            @Override
            publicvoidactionPerformed(ActionEventarg0) {
                // TODO Auto-generated method stub
                try {
                   if (client == null) {
                       client = newMqttClient(host, clienID, new MemoryPersistence());
                   }
 
                   if(!client.isConnected()) {
                       connect();
                   }
                   if (myTopic != null &&!myTopic.equals(textTopic.getText())) {
                       client.subscribe(myTopic);
                   }
                   client.subscribe(textTopic.getText());
                   myTopic = textTopic.getText();
 
                } catch (Exception e) {
                   e.printStackTrace();
                   showErrorMsg(e.toString());
                }
            }
        });
 
        textHost = new JTextArea();
       textHost.setText(host);
       textClientID = new JTextArea();
       textClientID.setText(clienID);
 
       panel.add(button);
       panel.add(subscribeButton);
       panelText.add(button2);
       panelText.add(new JLabel("mqtt地址"));
       panelText.add(textHost);
       panelText.add(new JLabel("ClienId"));
       panelText.add(textClientID);
       panelText.add(new JLabel("主题"));
        textTopic =new JTextArea();
 
       textTopic.setText(myTopicRoot);
       panelText.add(textTopic);
 
       textPublishMsg = new JTextArea();
        textPublishMsg.setText("@" + userToken + "@E@5@" + userToken + "@");
       panelText2.add(new JLabel("mqtt消息"));
       panelText2.add(textPublishMsg);
 
       container.add(panel, BorderLayout.NORTH);
       container.add(panelText, BorderLayout.CENTER);
       container.add(panelText2, BorderLayout.SOUTH);
        // try {
        // client = new MqttClient(host,clienID,
        // new MemoryPersistence());
        // connect();
        // } catch (Exception e) {
        // showErrorMsg(e.toString());
        // }
    }
 
 
 
 
 
 
 
 
    privateSSLSocketFactory getSSLSocktet(StringcaPath,String crtPath, String keyPath, String password) throws Exception {
        // CA certificate is used toauthenticate server
        CertificateFactorycAf = CertificateFactory.getInstance("X.509");
       FileInputStream caIn = new FileInputStream(caPath);
       X509Certificate ca = (X509Certificate) cAf.generateCertificate(caIn);
         KeyStorecaKs = KeyStore.getInstance("JKS");
         caKs.load(null, null);
        caKs.setCertificateEntry("ca-certificate", ca);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
        tmf.init(caKs);
 
       CertificateFactory cf = CertificateFactory.getInstance("X.509");
       FileInputStream crtIn = new FileInputStream(crtPath);
       X509Certificate caCert = (X509Certificate)cf.generateCertificate(crtIn);
 
       crtIn.close();
        // client key and certificates are sentto server so it can authenticate
        // us
        KeyStore ks= KeyStore.getInstance(KeyStore.getDefaultType());
//      ks.load(caIn,password.toCharArray());
        ks.load(null, null);
       ks.setCertificateEntry("certificate", caCert);
       ks.setKeyEntry("private-key", getPrivateKey(keyPath),password.toCharArray(),
                newjava.security.cert.Certificate[]{caCert} );
       KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
        kmf.init(ks, password.toCharArray());
//      keyIn.close();
 
        // finally, create SSL socket factory
        SSLContextcontext = SSLContext.getInstance("TLSv1");
 
       context.init(kmf.getKeyManagers(),tmf.getTrustManagers(), new SecureRandom());
 
        returncontext.getSocketFactory();
    }
 
 
 
 
 
    private String getPem(String path) throws Exception{
       FileInputStream fin=new FileInputStream(path);
       BufferedReader br= new BufferedReader(new InputStreamReader(fin)); 
        String readLine= null; 
       StringBuilder sb= new StringBuilder(); 
        while((readLine=br.readLine())!=null){ 
            if(readLine.charAt(0)=='-'){ 
                continue; 
            }else{ 
               sb.append(readLine); 
               sb.append('\r'); 
            } 
        } 
       fin.close();
        return sb.toString();
    }
 
    public PrivateKey getPrivateKey(String path) throws Exception{ 
 
       org.apache.commons.codec.binary.Base64 base64=new Base64();
        byte[] buffer=   base64.decode(getPem(path));
 
       PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);
        KeyFactorykeyFactory= KeyFactory.getInstance("RSA"); 
        return (RSAPrivateKey)keyFactory.generatePrivate(keySpec); 
 
 
    } 
 
 
 
    privatevoidconnect() {
 
       MqttConnectOptions options = new MqttConnectOptions();
       options.setCleanSession(false);
        // options.setUserName(userName);
        //options.setPassword(passWord.toCharArray());
        // 设置超时时间
        // options.setConnectionTimeout(10);
        // 设置会话心跳时间
        // options.setKeepAliveInterval(20);
        // try {
        // options.setWill("willtest","SENDgpslost".getBytes(), 1, false);
        // } catch (Exception e1) {
        // // TODO Auto-generated catch block
        // System.out.print(e1);
        // }
        try {
            if(!SSLSocketFactoryFactory.isSupportedOnJVM()) {
               System.out.print("isSupportedOnJVM=false");
            }
 
            SSLSocketFactoryfactory=getSSLSocktet("F:/ssl/ca.crt","F:/ssl/client.crt","F:/ssl/client.pem","brt123");
 
           options.setSocketFactory(factory);
           client.setCallback(new MqttCallback() {
 
                @Override
                publicvoidconnectionLost(Throwablecause) {
                   System.out.println("connectionLost-----------");
                }
 
                @Override
                publicvoiddeliveryComplete(IMqttDeliveryTokentoken) {
                   System.out.println("deliveryComplete---------" +token.isComplete());
                }
 
                @Override
                publicvoidmessageArrived(String topic,MqttMessage arg1) throws Exception {
                   System.out.println("messageArrived----------");
                   String msg = newString(arg1.getPayload());
                   showErrorMsg("主题:" + topic + "\r\n消息:" + msg);
                }
            });
 
            topic =client.getTopic(myTopicRoot + userToken);
            client.connect(options);
 
        } catch (Exception e) {
           e.printStackTrace();
        }
 
    }
 
    publicvoidpublishMsg(String topoc,String msg) {
        message = new MqttMessage();
       message.setQos(0);
       message.setRetained(false);
       System.out.println(message.isRetained() + "------ratained状态");
 
        try {
           message.setPayload(msg.getBytes("UTF-8"));
           client.publish(topoc, message);
        } catch (Exception e) {
            e.printStackTrace();
           showErrorMsg(e.toString());
        }
    }
 
    privatevoidshowErrorMsg(String msg) {
       JOptionPane.showMessageDialog(null, msg);
    }
 
}


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值