MQTT作为android客户端的push消息推送协议。android客户端需要通过SSL/TLS连接mqtt代理服务器,实现消息的加密传输。实现这个流程需要提供两个方面的支持,一个是mqtt协议客户端实现,另一个是mqtt代理服务器。 有很多开源的mqtt代理服务器,我选择使用mosquitto broker.
-
mosquitto 安装到windows 上,我使用windows作为mosquitto代理服务器
2. 安装openssl
3.生成服务器证书
openssl req -new -x509 -days 3650 -keyout m2mqtt_ca.key -out m2mqtt_ca.crt
openssl genrsa -des3 -out m2mqtt_srv.key 1024
openssl req -out m2mqtt_srv.csr -key m2mqtt_srv.key -new
openssl x509 -req -in m2mqtt_srv.csr -CA m2mqtt_ca.crt -CAkey m2mqtt_ca.key -CAcreateserial -out m2mqtt_srv.crt -days 3650
android仅支持BKS格式的证书 ,使用keytool装换CRT成为BKS格式,
4.生成BKS格式证书
先下载bcprov-jdk16-141.jar 放到1.6.0.jdk/Contents/Home/lib/ext目录下
keytool -importcert -keystore test.bks -file m2mqtt_ca.crt -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
5.配置服务器端
修改 mosquitto_m2mqtt.conf
-
bind_address : server name (in my case bind_address ppatierno-PC);
-
port : MQTT port for SSL/TLS is 8883 (port 8883);
-
cafile : path for CA certificate (cafile C:\OpenSSL-Win64\bin\PEM\m2mqtt_ca.crt);
-
certfile : path for server certificate (certfile C:\OpenSSL-Win64\bin\PEM\m2mqtt_srv.crt);
-
keyfile : path server private key (keyfile C:\OpenSSL-Win64\bin\PEM\m2mqtt_srv.key);
-
tls_version : TLS version (tls_version tlsv1);
启动服务器
mosquitto –c mosquitto_m2mqtt.conf –v
6.android客户端,添加信任证书代码
SSLContext context;
KeyStore ts = KeyStore.getInstance("BKS");
ts.load(getResources().openRawResource(R.raw.test),
"123456".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory
.getInstance("X509");
tmf.init(ts);
TrustManager[] tm = tmf.getTrustManagers();
context = SSLContext.getInstance("TLS");
context.init(null, tm, null);
// SocketFactory factory= SSLSocketFactory.getDefault();
// Socket socket =factory.createSocket("localhost", 10000);
SocketFactory factory = context.getSocketFactory();
conOpt.setSocketFactory(factory);
7.源码下载地址
git clone https://github.com/widercode/AndroidMqttWithSSLSample.git
Mosquito使用SSL/TLS进行安全通信时的使用方法
2014-04-22 12:52:50| 分类: mqtt | 标签: |举报 |字号大中小 订阅
1、 SSL简介
SSL(SecureSocket Layer)安全套接层,是网景公司提出的用于保证Server与client之间安全通信的一种协议,该协议位于TCP/IP协议与各应用层协议之间,即SSL独立于各应用层协议,因此各应用层协议可以透明地调用SSL来保证自身传输的安全性,SSL与TCP/IP协议及其其他应用层协议之间的关系如图1所示。
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/OrWhxloijjygsMxZnc0Qiw==/4946641240813358635.jpg)
图1 SSL/TLS协议与应用层协议及tcp/ip层协议的关系
目前,SSL被大量应用于http的安全通信中,MQTT协议与http协议同样属于应用层协议,因此也可以像http协议一样使用ssl为自己的通信提供安全保证。
SSL与TLS(Transport LayerSecurity Protocol)之间的关系:TLS(TransportLayer Security,传输层安全协议)是IETF(InternetEngineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。
开源的算法Openssl对SSL以及TLS1.0都能提供较好的支持,因此,后面使用mosquitto时也采用Openssl作为SSL的实现。
2、 Openssl安装与常用命令说明
2.1、安装
在CentOS6.3上安装Openssl的命令如下:
yum install openssl-devel
注意在安装的时候要安装“openssl-devel”,而不是“openssl”。
安装成功之后可以使用如下命令查看openssl的版本:
[root@cddserver1~]# openssl version
OpenSSL1.0.1e-fips 11 Feb 2013
2.2、常用命令说明
SSL在身份认证过程中需要有一个双方都信任的CA签发的证书,CA签发证书是需要收费的,但是在测试过程中,可以自己产生一个CA,然后用自己产生的CA签发证书,下面的mosquitto的ssl功能的测试过程就是采用这一方式,其过程如下:
1) 产生自己的CA,该过程将为CA产生两个文件:ca.key和ca.crt(文件的名字可以修改),其中ca.key是我们自己产生的CA的“密钥文件“,ca.crt是我们自己产生的CA的”证书文件“,本步结束CA将拥有两个文件ca.key和ca.crt,然后将为CA产生的这两个文件分别拷贝到mosquitto server及客户端所在的机子上;
2) 在server所在的机子上,使用这个自己产生的CA为mosquitto的server端签发证书,本步将产生server.key,server.csr和server.crt三个文件(文件名字可以修改),这里server.csr是签发证书的请求文件,CA为server端产生证书文件时将用到它,产生完证书文件之后,该文件就不用了;server.key和 server.crt这两个文件将会在后续的SSL通信过程中用到。
3) 在测试客户端所用的机子上,使用这个自己产生的CA为mosquitto的客户端签发证书;本步将产生client.key,client.csr和client.crt三个文件(文件名字可以修改),各文件的含义跟server端类似。
上述三个过程将使用openssl完成,将用到如下几条相关的命令:
l 产生CA的key和证书文件
openssl req -new -x509 -days 36500-extensions v3_ca -keyout ca.key -out ca.crt
该命令将为CA产生一个名字为“ca.key”的key文件和一个名字为“ca.crt”的证书文件,这个crt就是CA自己给自己签名的证书文件。
该命令中选项“-x509”表示该条命令将产生自签名的证书,一般都是测试的时候采用。
l 为mosquittoserver私钥文件“server.key”和证书文件”server.crt”
(1)为mosquittoserver产生一个私钥文件server.key
opensslgenrsa -out server.key 2048
该命令将产生一个不加密的RSA私钥,其中参数“2048”表示私钥的长度,这里产生的私钥文件“server.key”将在下一步使用,同时在mosquitto程序的配置文件中也需要使用。
如果需要为产生的RSA私钥加密,则需加上选项“-des3”,对私钥文件加密之后,后续使用该密钥的时候都要求输入密码。产生加密RSA私钥文件的命令如下:
opensslgenrsa -des3 -out server.key 2048
如果为RSA私钥文件加密了,则一定要记好密码,后面产生csr文件时以及后续使用该私钥文件都会用到该密码。
(2)为mosquitto server产生一个签发证书的请求文件“server.csr”
opensslreq -out server.csr -key server.key -new
该命令将使用上一步产生的“server.key”文件为server产生一个签发证书所需要的请求文件:server.csr,使用该文件向CA发送请求才会得到CA签发的证书。
(3)CA为mosquitto server产生一个证书文件
openssl x509 -req -in server.csr -CA ca.crt-CAkey ca.key -CAcreateserial -out server.crt -days 36500
该命令将使用CA的密钥文件ca.key,CA的证书文件ca.crt和上一步为mosquitto server产生证书请求文件server.csr文件这三个文件向CA请求产生一个证书文件,证书文件的名字为:server.crt。该命令中的36500可以修改为自己定义的时间值。
l 为mosquitto的客户端程序产生私钥文件”client.key”和证书文件“client.crt”,过程与为server端类似,这里将不再累述。
(1) 为mosquittoserver产生一个私钥文件”client.key”
openssl genrsa-out client.key 2048
(2) 为mosquitto客户端产生一个签发证书的请求文件“client.csr “
openssl req-out client.csr -key client.key-new
产生证书请求文件时需要第一步产生的私钥文件client.key作为输入。
(3) CA为mosquitto客户端产生一个证书文件”client.crt”
opensslx509 -req -in client.csr-CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 36500
3、 Mosquito使用ssl功能的具体操作方法
下面的例子中,将使用:A(192.168.4.222),B(192.168.4.223)和C(192.168.4.221)这三台机子,其中使用A制作CA证书;在B上运行mosquitto实例,在C上运行一个订阅端,一个发布端。
3.1、产生CA
测试过程中CA在主机cddserver3上;另外,测试过程中,无需采用真正的CA,使用我们自己产生的CA即可,使用命令为:
openssl req -new-x509 -days 36500 -extensions v3_ca -keyout ca.key -out ca.crt
命令执行过程中将需要输入国别、省份(或州)、市、Common Name等参数,其中最需要注意的是” Common Name”这个参数,它必须是当前机子的IP地址,使用主机名不行。如下截图所示
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/AoU32886OhvqoZsQzM-DDQ==/6608216615538941449.jpg)
特别要注意的是Common Name参数需要填写主机的IP地址,使用主机名不行。
本步结束即产生自己的CA,它有两个文件“ca.key“和”ca.crt“:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/OLScU8mVS3DazsXYlvs_RQ==/3240058457016737047.jpg)
3.2、使用自己产生的CA为server签发证书
将3.1中产生的CA文件拷贝mosquitto server所在机子上(其主机名字为cddserver3)的某个位置,例如:/home/jason.hou/ssl,然后使用该CA为server产生证书文件。如下截图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img0.ph.126.net/T6jRlMPqAaJE99mMbd7LJQ==/4854880398405806691.jpg)
(1)产生密钥文件server.key,为了减少测试过程中总是提出输入密码的麻烦,这里将为server产生一个不加密的密钥文件。过程如下截图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img0.ph.126.net/aljBs0LXfIJpSISAIVUHzQ==/6608270491608702006.jpg)
图3-4
(2)产生证书签发的请求文件server.csr。过程如下截图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img2.ph.126.net/9braaj4VrVZoZ2EMCUrDBQ==/6608182530678480086.jpg)
图3-5
同样该过程需要注意Common Name参数需要填写当前主机的IP地址。
(3)为mosquitto server产生证书文件:server.crt,这一步将需要输入CA的密码,同样,这里也可以看到刚才为CA输入的参数国别、省份等参数,过程如下截图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/PxKrWV814--RlLfLkpn6yA==/6597566745914220793.jpg)
图3-6
3.3、使用自己产生的CA为client签发证书
该过程与3.2类似。首先,将3.1中产生的CA文件拷贝mosquittoclient所在机子(其主机名字为cddserver1)上的某个位置,例如:/home/jason.hou/ssl,然后使用该CA为server产生证书文件。如下截图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img2.ph.126.net/4atmJ2rMtgns-h4f4iUVZw==/1396397359562398034.jpg)
图3-7
(1) 产生密钥文件client.key,过程如下截图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/7xcy1lbTX9qYonxPkdE3lQ==/3191926235999060584.jpg)
图3-8
(2) 产生证书请求文件client.csr,过程如下截图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img0.ph.126.net/14sRhPFWAi-OdSDCHHuLlA==/2987856877883788656.jpg)
图3-9
(3) 为客户产生证书文件Client.crt,过程如下截图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img0.ph.126.net/8iF5oWyp-s3G7jYZ_cdsGQ==/1706582783897017179.jpg)
图3-10
3.4、修改mosquitto配置文件
为了使用SSL功能Mosquito的配置文件mosquitto.conf需要修改以下四个地方:
(1) port 参数,mosquitto官方网站建议在使用功能的时候使用8883端口,如下所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img2.ph.126.net/bmX6avEvTzf9oEKZs56wNw==/6608414527631940089.jpg)
图3-11(1)
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/5EbW4aJoo70KdiwfZV-9QQ==/2876392787106605230.jpg)
图3-11(2)
(2) 修改cafile参数,该参数表示CA的证书文件的位置,需将其设置为正确的位置,例如下图所示
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/ucw2atmBRrNDuBBH4seSvg==/2668664254293837175.jpg)
图3-12
(3) 修改certfile参数,该参数表示CA为server端签发的证书文件的位置,如上图所示。
(4) 修改keyfile参数,该参数表示server端使用的key文件的位置。如上图所示。
3.5、运行程序
(1)启动mosquitto server端
使用修改后的配置文件启动mosquitto程序,上面修改的配置文件的路径,在mosquitto目录下,因此需要用-c参数指定其位置,如下图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img2.ph.126.net/Qnmx2IF5M25nWrqOTNiETw==/56857945396181138.jpg)
图3-13
(2)启动订阅端:
订阅端所在ssl文件的路径为:/home/jason.hou/ssl,启动时所使用的命令为:
./mosquitto_sub-h 192.168.4.223 -i 111 -p 8883 -t "111" --cafile/home/jason.hou/ssl/ca.crt --cert /home/jason.hou/ssl/client.crt --key/home/jason.hou/ssl/client.key
如下图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/oIUErLYhoRA8zCq5EzXqfQ==/785878135076494639.jpg)
图3-14
(4) 启动发布端
启动时所使用的命令为:
./mosquitto_pub -h192.168.4.223 -p 8883 -t "111" -m "this is jason.hou"--cafile /home/jason.hou/ssl/ca.crt --cert /home/jason.hou/ssl/client.crt --key/home/jason.hou/ssl/client.key
如下图所示:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img0.ph.126.net/mRAm4H7JpImjHWLm_FGTlw==/842736080371931448.jpg)
图3-15
(5) 发布消息之后,mosquitto、订阅端、发布端的截图如下:
Mosquito:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img0.ph.126.net/Ctp3SNUPJhiUmQs9jFyUsA==/1469299378530173394.jpg)
图3-16
发布端:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img0.ph.126.net/j2Pt-ekv_YyuoTXYt3Pq6A==/719450040572907246.jpg)
图3-17
订阅端:
![[原]Mosquito使用SSL/TLS进行安全通信时的使用方法 - 逍遥子 - 逍遥子 曰:](http://img1.ph.126.net/D1sAB8Pg5Cl4boU-fV3z9A==/4851784173661943059.jpg)
图3-18
1、 注意事项
(1) 制作签发证书的请求文件时,需要输入Common Name参数,此参数一定为当前主机的IP地址,否则将会显示证书错误。
(2) 如果不想SSL在身份认证的时候检查主机名(也即上面不检查第1条中Common Name参数),则需要在启动订阅端的时候,加上“--insecure”参数,例如:
./mosquitto_sub-h 192.168.4.223 -i 111 -p 8883 -t "111" --cafile/home/jason.hou/ssl/ca.crt --cert /home/jason.hou/ssl/client.crt --key/home/jason.hou/ssl/client.key --insecure
(3) 自测过程中,server端与所有客户端所使用的证书必须由一个CA签发,否则,将会提示CA不识别的问题。
问题提示为:
1398166026:New connection from 192.168.4.221 on port 8883.
1398166026:OpenSSL Error: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknownca
1398166026:OpenSSL Error: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshakefailure
1398166026:Socket error on client (null), disconnecting.
如下图所示: