透過 SSL 連接 Android 上的 MQTT 用戶端範例 Java 應用程式
開始進行透過 SSL 連接至 IBM® WebSphere® MQ 的範例 Android MQTT 用戶端。
開始之前
- 您必須能夠存取支援 MQTT protocol over SSL 的 MQTT version 3.1 伺服器。
- 如果用戶端與伺服器之間有防火牆,請確認它不會封鎖 MQTT 資料流量。
- 如果您要在早期 Android 裝置上測試連線,則可能需要 SD 卡才能將憑證傳送至裝置。
- 如果您要在虛擬 Android 裝置上測試連線,請為虛擬裝置配置 SD 卡。
- SSL 通道必須已啟動。
關於此作業
完成此作業以透過 SSL 執行 Android 的 MQTT 用戶端範例 Java 應用程式 。 成功的 SSL 連線會在 Android 裝置與 MQTT 伺服器之間建立安全的加密通道。 伺服器的身分已經過鑑別。
使用 Android,您可以使用 SSL 來鑑別伺服器。 您也可以鑑別裝置,雖然範例應用程式並不支援這樣做。 若要鑑別裝置,請使用 KeyChain API,或使用 JAAS 來鑑別 MQTT Android 應用程式所提供的用戶端 ID、用戶端 IP 位址或使用者名稱及密碼。
您安裝到 Android 信任儲存庫中的任何 X.509 憑證都必須由憑證管理中心簽署。 在此範例中,您建立憑證管理中心,它會簽署您在 Android 裝置中安裝的憑證。 許多主要憑證已預先安裝至 Android 裝置。
在安裝授信憑證之前,您必須在 Android 裝置上建立鎖定。 鎖定可防止他人在您不知情的狀況下於裝置上安裝憑證。
程序
結果
MQTTExerciser 應用程式需要略長的時間才會連接並交換訊息,但在其他方面的行為與透過非安全連線進行連接時沒有任何差異。
為 Windows配置 SSL 憑證的 Script 範例
指令檔範例會建立憑證及憑證儲存庫,如作業中的步驟所述。 此外,此範例還會將 MQTT 用戶端佇列管理程式設定為使用伺服器憑證儲存庫。 範例會呼叫 IBM WebSphere MQ隨附的 SampleMQM.bat Script ,來刪除並重建佇列管理程式。
- initcert.bat
- initcert.bat 會設定 keytool 及 openSSL 指令所需之憑證及其他參數的名稱和路徑。 Script 中的註解說明了這些設定。
@echo off @rem Set the path where you installed the MQTT SDK @rem and short cuts to the samples directories. set SDKRoot=C:\MQTT set jsamppath=%SDKRoot%\sdk\clients\java\samples set csamppath=%SDKRoot%\sdk\clients\c\samples
@rem Set the paths to Version 7 of the JDK @rem and to the directory where you built the openSSL package. @rem Set short cuts to the tools. set javapath=C:\Program Files\IBM\Java70 set keytool="%javapath%\jre\bin\keytool.exe" set ikeyman="%javapath%\jre\bin\ikeyman.exe" set openssl=%SDKRoot%\openSSL set runopenssl="%openssl%\bin\openssl"
@rem Set the path to where certificates are to be stored, @rem and set global security parameters. @rem Omit set password, and the security tools prompt you for passwords. @rem Validity is the expiry time of the certificates in days. set certpath=%SDKRoot%\Certificates set password=password set validity=5000 set algorithm=RSA
@rem Set the certificate authority (CA) jks keystore and certificate parameters. @rem Omit this step, unless you are defining your own certificate authority. @rem The CA keystore contains the key-pair for your own certificate authority. @rem You must protect the CA keystore. @rem The CA certificate is the self-signed certificate authority public certificate. @rem It is commonly known as the CA root certificate. set caalias=caalias set cadname="CN=mqttca.ibm.id.com, OU=ID, O=IBM, L=Hursley, S=Hants, C=GB" set cakeypass=%password% @rem ca key store set cajkskeystore=%certpath%\cakeystore.jks set cajkskeystorepass=%password% @rem ca certificate (root certificate) set cacert=%certpath%\cacert.cer
@rem Set the server jks keystore and certificate parameters. @rem The server keystore contains the key-pair for the server. @rem You must protect the server keystore. @rem If you then export the server certificate it is self-signed. @rem Alternatively, if you export a certificate signing request (CSR) @rem from the server keystore for the server key, @rem and import the signed certificate back into the same keystore, @rem it forms a certificate chain. @rem The certificate chain links the server certificate to the CA. @rem When you now export the server certificate, @rem the exported certificate includes the certificate chain. set srvalias=srvalias set srvdname="CN=mqttserver.ibm.id.com, OU=ID, O=IBM, L=Hursley, S=Hants, C=GB" set srvkeypass=%password% @rem server key stores set srvjkskeystore=%certpath%\srvkeystore.jks set srvjkskeystorepass=%password% @rem server certificates set srvcertreq=%certpath%\srvcertreq.csr set srvcertcasigned=%certpath%\srvcertcasigned.cer set srvcertselfsigned=%certpath%\srvcertselfsigned.cer
@rem Set the client jks keystore and certificate parameters @rem Omit this step, unless you are authenticating clients. @rem The client keystore contains the key-pair for the client. @rem You must protect the client keystore. @rem If you then export the client certificate it is self-signed. @rem Alternatively, if you export a certificate signing request (CSR) @rem from the client keystore for the client key, @rem and import the signed certificate back into the same keystore, @rem it forms a certificate chain. @rem The certificate chain links the client certificate to the CA. @rem When you now export the client certificate, @rem the exported certificate includes the certificate chain. set cltalias=cltalias set cltdname="CN=mqttclient.ibm.id.com, OU=ID, O=IBM, L=Hursley, S=Hants, C=GB" set cltkeypass=%password% @rem client key stores set cltjkskeystore=%certpath%\cltkeystore.jks set cltjkskeystorepass=%password% set cltcertreq=%certpath%\cltcertreq.csr set cltcertcasigned=%certpath%\cltcacertsigned.cer set cltcertselfsigned=%certpath%\cltcertselfsigned.cer
@rem Set the paths to the client truststores signed by CA and signed by server key. @rem You only need to define one of the trust stores. @rem A trust store holds certificates that you trust, @rem which are used to authenticate untrusted certificates. @rem In this example, when the client authenticates the MQTT server it connects to, @rem it authenticates the certificate it is sent by the server @rem with the certificates in its trust store. @rem For example, the MQTT server sends its server certificate, @rem and the client authenticates it with either the same server certificate @rem that you have stored in the cltsrvtruststore.jks trust store, @rem or against the CA certificate, if the server certificate is signed by the CA. set cltcajkstruststore=%certpath%\cltcatruststore.jks set cltcajkstruststorepass=%password% set cltsrvjkstruststore=%certpath%\cltsrvtruststore.jks set cltsrvjkstruststorepass=%password%
@rem Set the paths to the client PKCS12 and PEM key and trust stores. @rem Omit this step, unless you are configuring a C or iOS client. @rem You only need to define either one of the trust stores for storing CA @rem or server signed server certificates. set cltp12keystore=%certpath%\cltkeystore.p12 set cltp12keystorepass=%password% set cltpemkeystore=%certpath%\cltkeystore.pem set cltpemkeystorepass=%password% set cltcap12truststore=%certpath%\cltcatruststore.p12 set cltcap12truststorepass=%password% set cltcapemtruststore=%certpath%\cltcatruststore.pem set cltcapemtruststorepass=%password% set cltsrvp12truststore=%certpath%\cltsrvtruststore.p12 set cltsrvp12truststorepass=%password% set cltsrvpemtruststore=%certpath%\cltsrvtruststore.pem set cltsrvpemtruststorepass=%password%
@rem set WMQ Variables set authopt=NEVER set authreq=REQUIRED set qm=MQXR_SAMPLE_QM set host=localhost set mcauser='Guest' set portsslopt=8884 set chlopt=SSLOPT set portsslreq=8885 set chlreq=SSLREQ set portws=1886 set chlws=PLAINWS set chlssloptws=SSLOPTWS set portssloptws=8886 set chlsslreqws=SSLREQWS set portsslreqws=8887 set mqlog=%certpath%\wmq.log
- cleancert.bat
- cleancert.bat Script 中的指令會刪除 MQTT 用戶端佇列管理程式,以確保伺服器憑證儲存庫未鎖定,然後刪除範例安全 Script 所建立的所有金鑰儲存庫及憑證。
@rem Delete the MQTT sample queue manager, MQXR_SAMPLE_QM call "%MQ_FILE_PATH%\bin\setmqenv" -s endmqm -i %qm% dltmqm %qm%
@rem Erase all the certificates and key stores created by the sample scripts. erase %cajkskeystore% erase %cacert% erase %srvjkskeystore% erase %srvcertreq% erase %srvcertcasigned% erase %srvcertselfsigned% erase %cltjkskeystore% erase %cltp12keystore% erase %cltpemkeystore% erase %cltcertreq% erase %cltcertcasigned% erase %cltcertselfsigned% erase %cltcajkstruststore% erase %cltcap12truststore% erase %cltcapemtruststore% erase %cltsrvjkstruststore% erase %cltsrvp12truststore% erase %cltsrvpemtruststore% erase %mqlog% @echo Cleared all certificates dir %certpath%\*.* /b
- genkeys.bat
- genkeys.bat Script 中的指令會為您的專用憑證管理中心、伺服器及用戶端建立金鑰組。
@rem @echo ________________________________________________________________________________ @echo Generate %caalias%, %srvalias%, and %cltalias% key-pairs in %cajkskeystore%, %srvjkskeystore%, and %cltjkskeystore% @rem @rem -- Generate a client certificate and a private key pair @rem Omit this step, unless you are authenticating clients. %keytool% -genkeypair -noprompt -alias %cltalias% -dname %cltdname% -keystore %cltjkskeystore% -storepass %cltjkskeystorepass% -keypass %cltkeypass% -keyalg %algorithm% -validity %validity%
@rem -- Generate a server certificate and private key pair %keytool% -genkeypair -noprompt -alias %srvalias% -dname %srvdname% -keystore %srvjkskeystore% -storepass %srvjkskeystorepass% -keypass %srvkeypass% -keyalg %algorithm% -validity %validity%
@rem Create CA, client and server key-pairs @rem -- Generate a CA certificate and private key pair - The extension asserts this is a certificate authority certificate, which is required to import into firefox %keytool% -genkeypair -noprompt -ext bc=ca:true -alias %caalias% -dname %cadname% -keystore %cajkskeystore% -storepass %cajkskeystorepass% -keypass %cakeypass% -keyalg %algorithm% -validity %validity%
- sscerts.bat
- sscerts.bat Script 中的指令會從其金鑰儲存庫匯出用戶端及伺服器自簽憑證,然後將伺服器憑證匯入用戶端信任儲存庫,並將用戶端憑證匯入伺服器金鑰儲存庫。 伺服器沒有信任儲存庫。 這些指令會從用戶端 JKS 信任儲存庫,以 PEM 的格式建立用戶端信任儲存庫。
@rem @echo ________________________________________________________________________________ @echo Export self-signed certificates: %srvcertselfsigned% and %cltcertselfsigned% @rem Export Server public certificate %keytool% -exportcert -noprompt -rfc -alias %srvalias% -keystore %srvjkskeystore% -storepass %srvjkskeystorepass% -file %srvcertselfsigned% @rem Export Client public certificate @rem Omit this step, unless you are authenticating clients. %keytool% -exportcert -noprompt -rfc -alias %cltalias% -keystore %cltjkskeystore% -storepass %cltjkskeystorepass% -file %cltcertselfsigned%
@rem @echo ________________________________________________________________________________ @echo Add selfsigned server certificate %srvcertselfsigned% to client trust store: %cltsrvjkstruststore% @rem Import the server certificate into the client-server trust store (for server self-signed authentication) %keytool% -import -noprompt -alias %srvalias% -file %srvcertselfsigned% -keystore %cltsrvjkstruststore% -storepass %cltsrvjkstruststorepass%
@rem @echo ________________________________________________________________________________ @echo Add selfsigned client certificate %cltcertselfsigned% to server trust store: %srvjkskeystore% @rem Import the client certificate into the server trust store (for client self-signed authentication) @rem Omit this step, unless you are authenticating clients. %keytool% -import -noprompt -alias %cltalias% -file %cltcertselfsigned% -keystore %srvjkskeystore% -storepass %srvjkskeystorepass%
@rem @echo ________________________________________________________________________________ @echo Create a pem client-server trust store from the jks client-server trust store: %cltsrvpemtruststore% @rem %keytool% -importkeystore -noprompt -srckeystore %cltsrvjkstruststore% -destkeystore %cltsrvp12truststore% -srcstoretype jks -deststoretype pkcs12 -srcstorepass %cltsrvjkstruststorepass% -deststorepass %cltsrvp12truststorepass% %openssl%\bin\openssl pkcs12 -in %cltsrvp12truststore% -out %cltsrvpemtruststore% -passin pass:%cltsrvp12truststorepass% -passout pass:%cltsrvpemtruststorepass%@rem @rem @echo ________________________________________________________________________________ @echo Create a pem client key store from the jks client keystore @rem Omit this step, unless you are configuring a C or iOS client. @rem %keytool% -importkeystore -noprompt -srckeystore %cltjkskeystore% -destkeystore %cltp12keystore% -srcstoretype jks -deststoretype pkcs12 -srcstorepass %cltjkskeystorepass% -deststorepass %cltp12keystorepass% %openssl%\bin\openssl pkcs12 -in %cltp12keystore% -out %cltpemkeystore% -passin pass:%cltp12keystorepass% -passout pass:%cltpemkeystorepass%
- cacerts.bat
- 此 Script 會將憑證管理中心主要憑證匯入專用金鑰儲存庫。 需要 CA 主要憑證,才可在主要憑證與已簽章的憑證之間建立金鑰鏈。 cacerts.bat Script 會從其金鑰儲存庫匯出用戶端及伺服器憑證申請。 Script 會使用 cajkskeystore.jks 金鑰儲存庫中專用憑證管理中心的金鑰,來簽署憑證申請,然後將已簽章的憑證匯回提出申請的同一個金鑰儲存庫。 匯入會使用 CA 主要憑證建立憑證鏈。 Script 會從用戶端 JKS 信任儲存庫,以 PEM 的格式建立用戶端信任儲存庫。
@rem @echo ________________________________________________________________________________ @echo Export self-signed certificates: %cacert% @rem @rem Export CA public certificate %keytool% -exportcert -noprompt -rfc -alias %caalias% -keystore %cajkskeystore% -storepass %cajkskeystorepass% -file %cacert%
@rem @echo ________________________________________________________________________________ @echo Add CA to server key and client key and trust stores: %srvjkskeystore%, %cltjkskeystore%, %cltcajkstruststore%, @rem The CA certificate is necessary to create key chains in the client and server key stores, @rem and to certify key chains in the server key store and the client trust store @rem @rem Import the CA root certificate into the server key store %keytool% -import -noprompt -alias %caalias% -file %cacert% -keystore %srvjkskeystore% -storepass %srvjkskeystorepass% @rem Import the CA root certificate into the client key store @rem Omit this step, unless you are authenticating clients. %keytool% -import -noprompt -alias %caalias% -file %cacert% -keystore %cltjkskeystore% -storepass %cltjkskeystorepass% @rem Import the CA root certificate into the client ca-trust store (for ca chained authentication) %keytool% -import -noprompt -alias %caalias% -file %cacert% -keystore %cltcajkstruststore% -storepass %cltcajkstruststorepass%
@rem @echo ________________________________________________________________________________ @echo Create certificate signing requests: %srvcertreq% and %cltcertreq% @rem @rem Create a certificate signing request (CSR) for the server key %keytool% -certreq -alias %srvalias% -file %srvcertreq% -keypass %srvkeypass% -keystore %srvjkskeystore% -storepass %srvjkskeystorepass% @rem Create a certificate signing request (CSR) for the client key %keytool% -certreq -alias %cltalias% -file %cltcertreq% -keypass %cltkeypass% -keystore %cltjkskeystore% -storepass %cltjkskeystorepass%
@rem @echo ________________________________________________________________________________ @echo Sign certificate requests: %srvcertcasigned% and %cltcertcasigned% @rem The requests are signed with the ca key in the cajkskeystore.jks keystore @rem @rem Sign server certificate request %keytool% -gencert -infile %srvcertreq% -outfile %srvcertcasigned% -alias %caalias% -keystore %cajkskeystore% -storepass %cajkskeystorepass% -keypass %cakeypass% @rem Sign client certificate request @rem Omit this step, unless you are authenticating clients. %keytool% -gencert -infile %cltcertreq% -outfile %cltcertcasigned% -alias %caalias% -keystore %cajkskeystore% -storepass %cajkskeystorepass% -keypass %cakeypass%
@rem @echo ________________________________________________________________________________ @echo Import the signed certificates back into the key stores to create the key chain: %srvjkskeystore% and %cltjkskeystore% @rem @rem Import the signed server certificate %keytool% -import -noprompt -alias %srvalias% -file %srvcertcasigned% -keypass %srvkeypass% -keystore %srvjkskeystore% -storepass %srvjkskeystorepass% @rem Import the signed client certificate and key chain back into the client keystore %keytool% -import -noprompt -alias %cltalias% -file %cltcertcasigned% -keypass %cltkeypass% -keystore %cltjkskeystore% -storepass %cltjkskeystorepass% @rem @rem The CA certificate is needed in the server key store, and the client trust store @rem to verify the key chain sent from the client or server @echo Delete the CA certificate from %cltjkskeystore%: it causes a problem in converting keystore to pem @rem Omit this step, unless you are authenticating clients. %keytool% -delete -alias %caalias% -keystore %cltjkskeystore% -storepass %cltjkskeystorepass%
@rem @echo ________________________________________________________________________________ @echo Create a pem client-ca trust store from the jks client-ca trust store: %cltcapemtruststore% @rem Omit this step, unless you are configuring a C or iOS client. @rem %keytool% -importkeystore -noprompt -srckeystore %cltcajkstruststore% -destkeystore %cltcap12truststore% -srcstoretype jks -deststoretype pkcs12 -srcstorepass %cltcajkstruststorepass% -deststorepass %cltcap12truststorepass% %openssl%\bin\openssl pkcs12 -in %cltcap12truststore% -out %cltcapemtruststore% -passin pass:%cltcap12truststorepass% -passout pass:%cltpemtruststorepass%
@rem @echo ________________________________________________________________________________ @echo Create a pem client key store from the jks client keystore @rem Omit this step, unless you are configuring a C or iOS client. @rem %keytool% -importkeystore -noprompt -srckeystore %cltjkskeystore% -destkeystore %cltp12keystore% -srcstoretype jks -deststoretype pkcs12 -srcstorepass %cltjkskeystorepass% -deststorepass %cltp12keystorepass% %openssl%\bin\openssl pkcs12 -in %cltp12keystore% -out %cltpemkeystore% -passin pass:%cltp12keystorepass% -passout pass:%cltpemkeystorepass%
- mqcerts.bat
- Script 會列出憑證目錄中的金鑰儲存庫及憑證。 然後,它會建立 MQTT 範例佇列管理程式,並配置安全遙測通道。
@echo ________________________________________________________________________________ @echo List keystores and certificates dir %certpath%\*.* /b
@rem @echo Create queue manager and define mqtt channels and certificate stores call "%MQ_FILE_PATH%\mqxr\Samples\SampleMQM" >> %mqlog% echo DEFINE CHANNEL(%chlreq%) CHLTYPE(MQTT) TRPTYPE(TCP) PORT(%portsslreq%) SSLCAUTH(%authreq%) SSLKEYR('%srvjkskeystore%') SSLKEYP('%srvjkskeystorepass%') MCAUSER(%mcauser%) | runmqsc %qm% >> %mqlog% echo DEFINE CHANNEL(%chlopt%) CHLTYPE(MQTT) TRPTYPE(TCP) PORT(%portsslopt%) SSLCAUTH(%authopt%) SSLKEYR('%srvjkskeystore%') SSLKEYP('%srvjkskeystorepass%') MCAUSER(%mcauser%) | runmqsc %qm% >> %mqlog% echo DEFINE CHANNEL(%chlsslreqws%) CHLTYPE(MQTT) TRPTYPE(TCP) PORT(%portsslreqws%) SSLCAUTH(%authreq%) SSLKEYR('%srvjkskeystore%') SSLKEYP('%srvjkskeystorepass%') MCAUSER(%mcauser%) PROTOCOL(HTTP) | runmqsc %qm% >> %mqlog% echo DEFINE CHANNEL(%chlssloptws%) CHLTYPE(MQTT) TRPTYPE(TCP) PORT(%portssloptws%) SSLCAUTH(%authopt%) SSLKEYR('%srvjkskeystore%') SSLKEYP('%srvjkskeystorepass%') MCAUSER(%mcauser%) PROTOCOL(HTTP) | runmqsc %qm% >> %mqlog% echo DEFINE CHANNEL(%chlws%) CHLTYPE(MQTT) TRPTYPE(TCP) PORT(%portws%) MCAUSER(%mcauser%) PROTOCOL(HTTP) | runmqsc %qm% >> %mqlog% @echo MQ logs saved in %mqlog%echo