Hi. Im struggeling with connecting a device to my broker using TLS. My IoT device ask for certificate files when configure it for MQTTS. Its 3 options:
Server Root CA
Client Certificate
3 Client Private Key
I just dont get it how to create this files. What will be the best way and the most easy way of this 3 options?
Is this for creating server certificate (Server Root CA)?
What is this tool keytool? How do I get it?
Any other tip on how to create the required certificates?
Hope anyone can help my on my basic questions. Im somehow new to MQTT.
Thanks for your interest in MQTT and HiveMQ. Could you please clarify whether you have your own HiveMQ broker set up or you are using HiveMQ Cloud broker account?
In case if it is HiveMQ cloud broker, you can retrieve the server CA file as described in here: Frequently Asked Questions.
Keytool is a certificate management utility included with Java . It allows users to create a single store, called a keystore, that can hold multiple certificates within it. This file can then be assigned or installed to a server and used for SSL/TLS connections.
For generating all certificates described in the blog article that I have suggested above, we have prepared a helpful shell script. You can use it as a reference or save it to a file certly.sh and run it with bash:
#!/bin/bash
defaultPass="changeme"
hostname="hivemq"
#hostname input
read -p "please input the hostname of the broker: (default [$hostname]): " hostnameInput
hostname=${hostnameInput:-$hostname} # set the default Password (if user skip this entry)
echo "the hostname is: $hostname"
#password input
read -p "please input the password you wish to use: (default [$defaultPass]): " passInput
defaultPass=${passInput:-$defaultPass} # set the default Password (if user skip this entry)
echo "the password is: $defaultPass"
#default file names and passwords
brokerCertName="server"
brokerKeystoreName="broker-keystore"
brokerKeystorePass=$defaultPass
brokerTruststoreName="broker-truststore"
brokerTruststorePass=$defaultPass
clientCertName="client-cert"
clientKeyName="client-key"
clientKeyPass=$defaultPass
clientKeystoreName="client-keystore"
clientKeystorePass=$defaultPass
clientName="client"
clientTruststoreName="client-truststore"
clientTruststorePass=$defaultPass
#check the time
time1=$(date +%s)
#crate output directory
outDirName="certs_$time1"
mkdir $outDirName
#goto output directory
pushd $outDirName
#create new broker .jks keystore
keytool -genkey -keyalg RSA -alias "hivemq" -keystore $brokerKeystoreName.jks -storepass $brokerKeystorePass -validity 360 -keysize 2048 -dname "CN=$hostname"
#export broker's cert .pem from the keystore
keytool -exportcert -alias "hivemq" -keystore $brokerKeystoreName.jks -rfc -file $brokerCertName.pem -storepass $brokerKeystorePass
#convert broker .pem certificate to .crt
openssl x509 -outform der -in $brokerCertName.pem -out $brokerCertName.crt
#import broker cert. into new client truststore
printf "yes\n" |keytool -import -file $brokerCertName.crt -alias "client" -keystore $clientTruststoreName.jks -storepass $clientTruststorePass
#generate .pem based client certificate and convert to .crt
openssl req -x509 -newkey rsa:2048 -keyout $clientKeyName.pem -out $clientCertName.pem -days 360 -passout pass:$clientKeyPass -subj "/CN=$clientName"
openssl x509 -outform der -in $clientCertName.pem -out $clientCertName.crt
#import client-cert into the broker's truststore
printf "yes\n" |keytool -import -file $clientCertName.crt -alias "client" -keystore $brokerTruststoreName.jks -storepass $brokerTruststorePass
#create client P12 keystore
openssl pkcs12 -export -in $clientCertName.pem -inkey $clientKeyName.pem -certfile $clientCertName.pem -out $clientKeystoreName.p12 -passin pass:$clientKeyPass -passout pass:$clientKeystorePass;
#convert client P12 keystore to JKS keystore
keytool -importkeystore -srckeystore $clientKeystoreName.p12 -srcstoretype pkcs12 -destkeystore $clientKeystoreName.jks -deststoretype JKS -storepass $clientKeystorePass -srcstorepass $clientKeystorePass 2>/dev/null;
#restore original directory
popd
echo "$outDirName"
If at any point you require further help please do not hesitate and ask. Feel free to share your code and the text of error messages, if any error arises.
Hi. Im using HiveMQ Cloud broker account. Pay as you goā¦
I still cant make it. Its cryptic to me. So I was able to download a OpenSSL command tool. I inserted the suggested command: s_client -connect āMy broker URLā :8883 -showcerts < /dev/null 2> /dev/null | sed -n ā/BEGIN/,/END/pā > server.pem
But no furter explanations. This is cryptic to a newbe like meā¦ How is this working. I understand I have to replace the URL with my own broker URL, but what about all the other arguments in that string:
-showcerts < /dev/null 2> /dev/null | sed -n ā/BEGIN/,/END/pā > server.pem
What to do here?
Will this generate a file?
I tried to run this : s_client -connect 4ad85b7fade04d07911be2ac1da2f5e4.s2.eu.hivemq.cloud:8883
then i get this back:
currently, you opened the OpenSSL command line tool, via command openssl. However, thatās not required.
Just open your terminal (shell, bash, zsh) and use the full command with your URL.
The other arguments in this command are:
-showcerts ā shows the full certificate chain
< /dev/null 2> /dev/null ā closes the command and redirects stderr
sed -n ā/BEGIN/,/END/pā ā finds the begin and end of each certificate
> server.pem. ā redirects the output to the file server.pem
if you are using Windows you have to use the WSL (Windows Subsystem for Linux) to be able to use the whole command.
In the Windows Terminal you can use openssl s_client -connect brokerurl.s2.eu.hivemq.cloud:8883 -showcerts and you will see 3 certficates. Each certificate starts with the āBEGIN CERTIFICATEā line and end with the āEND CERTIFICATEā line.
Use the mouse and select each certificate one-by-one and copy paste them into a single file and name it server.pem and save it.
Finally, the server.pem file should look like:
I made the server.pem file as you suggest above, and using MQTT.fx - I selected the file as the āCA certifcate fileā.
MQTT.fx connected and all is good.
But, I donāt need to use this file to connect.
Instead, I can select the option āCA signed server certificateā - and it still connects fine.
What is the difference? why use the server.pem file at all? Does it provide any kind of security?
Iām completely confused by all this certificate stuff!
Hi Dominic,
I did as you instructed. I created a .pem file from the three certificates generated by openssl. However the device could not take a document above 4kb. This was 6kb. I got this feedback from vendor:
Your format may be a certificate issued by an intermediate authority, I am not sure if the certificate issued by the Root CA authority is the same
1. It may be the reason of openssl parameters, you can try to modify the parameters 2. The test only keeps a set of content from āBEGIN CERTIFICATEā to āEND CERTIFICATEā to see if it can be connected 3. Generally speaking, each ācertificateā should be less than 4KB; this is also the reason why āInvalid Fileā appears when burning the software and importing server.pem (6KB).
Any comment to this? Do I need all 3 certificates in the file?
Some systems do not trust the specific CA used by HiveMQ cloud, which is why using the ca.pem file is then necessary.
Thereās not difference in security whether or not the ca is trusted by the system or you specifically trust it via adding the ca.pem file.
I can connect to HiveMQ cloud using MQTTnet library for Visual Studio.
I didnāt need to refer to any certificates to do this.
So, is simply connecting to HiveMQ without any certificates involved a secure (and encrypted?) connection on itās own, or do I still need to use other certificates?
In my software MQTT connection window, there are the following inputs:
Broker address
Broker port
Client ID
Username
Password
UseTLS (tick box)
MQTT Version (3.1, 3.1.1 & 5.0)
Do I also need to include a ābrowse for certificate (pem?) fileā - just in case?
Can I conclude then, that if I also include a āBrowse for CA fileā option, & the client can connect to the TLS broker - then this is all the security I need to offer?
Is the data in this TLS connection encrypted and absolutely secure against hackers?
If so, then I think my work may be done in this respect.
Note that there is no -s (--secure) flag used here.
Note2: If you copy-paste my commands from here, sometimes the single quotes might get replaced by different quotes by the operating system. So, after you paste, please check that all the quotes are correct.
Iām trying to connect to HiveMQ cloud from a u-Blox module and I face very similar issues as to what youāve described Hans.
Iām trying to connect using SSL/TLS.
Just using the trusted root CA cert is not enough as I get āBroker connection refused, not authorizedā.
When using openssl to get the server.pem file, it includes three certificates and I canāt add it to the u-Blox module as itās āinvalid certificate/key formatā.
Trying to any one of the three certificates in the .pem-file doesnāt work either.
And, just as a reference, when I play with test.mosquitto.org, things work immediately when I add the trusted root CA cert for test.mosquitto.org. But something else is needed apparently when connecting to HiveMq cloud. But what? Or is this a limitation in the u-Blox module as the openssl-generated .pem-file with the entire chain canāt be added to the module?
For the TLS connection to the HiveMQ Cloud cluster it requires the TLS-SNI extension to be available and used. Is that the case with u-Blox module? Please take a look at this topic for more details:
I hope this helps,
Kind regards,
Dasha from HiveMQ Team
Iām not sure what you mean. The uBlox module I use support TLS/SSL and can success connect to mosquitto using port 8883, so I know that things work, and in my best scenario Iād use the HiveMQ trusted root CA cert only and thatās all. But it fail.
So something is different in terms of authentication and certificate/negotiation but I donāt understand what.
@Daria_H, reading your response a few times more realised that I read it wrong. You didnāt mention SSL, you mentioned SNI. Sorryā¦ I enabled SNI on the u-Blox module just now and guess what; the trusted root certificate and SNI was enough to make things work. Iām now connected to the HiveMQ cloud! Thanks!