Connecting devices to MindConnect IoT Extension - using Trusted Certificates¶
Devices can authenticate against MindConnect IoT Extension using X.509 client certificates. Devices can communicate using the MQTT interface of the platform, however, MQTT over WebSocket is not supported. MindConnect IoT Extension expects devices to connect using SSL on port 8883. Each environment individually defines whom it trusts by uploading the base CA certificate. Devices connecting to the platform with certificates are not required to provide the tenant ID, username, and password - authentication information will be obtained from the certificates.
This guide describes the step-by-step procedure to prepare and use Trusted Certificates in order to connect devices to MindConnect IoT Extension. For a detailed introduction of Trusted Certificates, see Introduction to X.509 certificates.
General Information
Execution Duration: 30 minutes
Tested with Insights Hub version: Release 8th October 2018
Prerequisites¶
- A Insights Hub account.
- Established MQTT connection to Insights Hub. For more information, see Integrating MQTT.
- The CA certificate may also be a self-signed certificate.
- Certificates must be uploaded as X.509 version 3 certificates.
- Uploaded certificates have to have set
BasicConstraints:[CA:true]
. - Devices need to trust the MindConnect IoT Extension server certificate.
- Certificates used by devices must contain the full certificate chain, including the uploaded CA certificate.
- Certificates used by devices must be signed either by uploaded CA certificates or by a chain of certificates signed by uploaded CA certificates.
- To generate certificates, ensure to have the OpenSSL toolkit installed.
Preparing Trusted Certificates¶
Creating a self-signed CA certificate¶
To create a self-signed CA certificate, proceed as follows:
- Create a directory for the root certificate and the signing configuration, for example:
mkdir /home/user/Desktop/caCertificate
- Navigate to the created directory and create a configuration file for the CA certificate:
touch caConfig.cnf
- Create a database file for keeping the history of certificates signed by the CA:
touch database.txt
- Create a serial file with initial serial number, which will be used to identify signed certificates. After assigning this serial to the signed certificate, the value in this file will be automatically incremented:
echo 1000 > serial
- Create subdirectories for signed certificates and the certificate revocation list:
mkdir deviceCertificates crl
-
Fill in the configuration file. Given below is an example configuration, which can be used for testing after changing the directory
dir
to your own. Consult a security specialist incase it must be used in the production environment[ ca ] default_ca = CA_default [ CA_default ] # Directory and file locations. dir = /home/user/Desktop/caCertificate certs = $dir # directory where the CA certificate will be stored. crl_dir = $dir/crl # directory where the certificate revocation list will be stored. new_certs_dir = $dir/deviceCertificates # directory where certificates signed by CA certificate will be stored. database = $dir/database.txt # database file, where the history of the certificates signing operations will be stored. serial = $dir/serial # directory to the file, which stores next value that will be assigned to signed certificate. # The CA key and CA certificate for signing other certificates. private_key = $dir/caKey.pem # CA private key which will be used for signing certificates. certificate = $dir/caCert.pem # CA certificate, which will be the issuer of signed certificate. default_md = sha256 # hash function default_days = 375 # default number of days for which the certificate will be valid since the date of its generation. preserve = no # if set to 'no' then it will determine the same order of the distinguished name in every signed certificate. policy = signing_policy # the name of the tag in this file that specifies the fields of the certificate. The fields have to be filled in or even match the CA certificate values to be signed. # For certificate revocation lists. crl = $crl_dir/caCrl.pem # CA certificate revocation list crlnumber = $crl_dir/crlnumber # serial, but for the certificate revocation list crl_extensions = crl_ext # the name of the tag in this file, which specifies certificates revocation list extensions, which will be added to the certificate revocation by default. default_crl_days = 30 # default number of days for which the certificate revocation list will be valid since the date of its generation. After that date it should be updated to see if there are new entries on the list. [ req ] default_bits = 4096 # default key size in bits. distinguished_name = req_distinguished_name # the name of the tag in this file, which specifies certificates fields description during certificate creation and eventually set some default values. string_mask = utf8only # permitted string type mask. default_md = sha256 # hash function. x509_extensions = v3_ca # the name of the tag in this file, which specifies certificates extensions, which will be added to the created certificate by default. # descriptions and default values of the created certificate fields. [ req_distinguished_name ] countryName = Country Name (2 letter code) stateOrProvinceName = State or Province Name localityName = Locality Name organizationName = Organization Name organizationalUnitName = Organizational Unit Name commonName = Common Name emailAddress = Email Address # A default value for each field can be set by adding an extra line with field name and postfix "_default". For example: "countryName_default = PL". If you add this line here, then leaving country name empty during certificate creation will result in the value "PL" being used. If the default value was specified there, but during certificate creation you do not want to use this value, then instead use "." as the value. It will leave the value empty and not use the default. # default extensions for the CA certificate. [ v3_ca ] subjectKeyIdentifier = hash # subject key value will be calculated using hash funtion. It's the recommended setting by PKIX. authorityKeyIdentifier = keyid:always,issuer # The subject key identifier will be copied from the parent certificate. It's the recommended setting by PKIX. basicConstraints = critical, CA:true, pathlen:10 # "critical" specifies that the extension is important and has to be read by the platform. CA says if it is the CA certificate so it can be used to sign different certificates. "pathlen" specifies the maximum path length between this certificate and the device certificate in the chain of certificates during authentication. Path length is set here only to show how it is done. If you do not want to specify max path length, you can keep only the "basicConstraints = critical, CA:true" part here. keyUsage = digitalSignature, cRLSign, keyCertSign # specifies permitted key usages. # Default extensions for the device certificate. This tag is not used directly anywhere in this file, but will be used from the command line to create signed certificate with "-extensions v3_signed" parameter. [ v3_signed ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer basicConstraints = critical, CA:false keyUsage = nonRepudiation, digitalSignature, keyEncipherment # default extensions for certificate revocation list [ crl_ext ] authorityKeyIdentifier=keyid:always # Policy of certificates signing. It specifies which certificate fields have to be filled in during certificate creation. There are three possible values here: # "optional" - field value can be empty # "supplied" - field value must be filled in # "match" - signed certificate field value must match the CA certificate value to be created [ signing_policy ] countryName = optional stateOrProvinceName = optional organizationName = optional organizationalUnitName = optional commonName = supplied # every certificate should have a unique common name, so this value should not be changed. emailAddress = optional
-
Create a private key with aes256 encryption and a length of at least 2048 bits. Also, a request to set the password will be made for the key during its creation:
openssl genrsa -aes256 -out caKey.pem 4096
- Create a self-signed certificate using specifications from the configuration file. The “days” parameter says how long this certificate will be valid since the generation, so set it as desired:
openssl req -config caConfig.cnf -key caKey.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out caCert.pem
- Print the created certificate with the command:
openssl x509 -noout -text -in caCert.pem
Creating an intermediate certificate¶
The intermediate certificate is signed by the CA certificate; however, it can also be used to sign device certificates. An intermediate certificate is not required if one common CA certificate is used to sign all the device certificates, therefore, this step can be skipped. However, if some certificates are needed between the CA certificate and the device certificate, then an intermediate certificate must be created.
Note
In MindConnect IoT Extension, the maximum length of the chain of certificates is currently restricted to 2, and therefore, it is not possible to use any intermediate certificate between the CA certificate and the device certificate.
To create an intermediate certificate, proceed as follows:
- Create a new directory for intermediate certificates inside the
caCertificate
path:mkdir intermediateCertificate
- Navigate to this directory and create a configuration file for the intermediate certificate:
touch intermediateConfig.cnf
- Create a database file for keeping the history of certificates signed by the intermediate certificate:
touch database.txt
- Create a serial file with initial serial number, which will be used to identify signed certificates:
echo 1000 > serial
- Create subdirectories for the signed certificates and the certificate revocation list:
mkdir deviceCertificates crl
- Fill in the configuration file as in the CA configuration and change the general directory (
dir
) to theintermediateCertificate
folder. Also, changeprivate_key
, certificate andcrl
names from current with “ca
” prefix to “intermediate
” prefix (for example:caKey.pem -> intermediateKey.pem
), because files with this prefix will be generated in the next steps. - Generate a private key for the intermediate certificate:
openssl genrsa -aes256 -out intermediateKey.pem 4096
- Generate a certificate signing request:
openssl req -config intermediateConfig.cnf -new -sha256 -key intermediateKey.pem -out intermediateCsr.pem
- Navigate to the
caCertificate
directory and generate a signed intermediate certificate. The CA configuration should be used here, because the private key specified in the configuration file will be used to sign the certificate:openssl ca -config caConfig.cnf -extensions v3_ca -days 3650 -notext -md sha256 -in intermediateCertificate/intermediateCsr.pem -out intermediateCertificate/intermediateCert.pem
- Verify if the generated certificate is correctly signed by CA:
openssl verify -CAfile caCert.pem intermediateCertificate/intermediateCert.pem
Creating a device certificate signed by CA or intermediate¶
To create device certificate , proceed as follows:
- Navigate to the directory of the
caCertificate
orintermediateCertificate
depending on which one is used to sign the device certificate. - Generate the private key for the new certificate:
openssl genrsa -aes256 -out deviceCertificates/deviceKey.pem 4096
- Generate the certificate signing request (change “
caConfig.cnf
” to “intermediateConfig.cnf
” if you are in theintermediateCertificate
directory):openssl req -config caConfig.cnf -new -sha256 -key deviceCertificates/deviceKey.pem -out deviceCertificates/deviceCsr.pem
The commonName of the device certificate, which will be requested to provide in the console, must match the ClientId of the device during the connection. - Generate the certificate signed by the CA or intermediate (change “
caConfig.cnf
” to “intermediateConfig.cnf
” if you are in theintermediateCertificate
directory):openssl ca -config caConfig.cnf -extensions v3_signed -days 365 -notext -md sha256 -in deviceCertificates/deviceCsr.pem -out deviceCertificates/deviceCert.pem
- Verify if the generated certificate is correctly signed by CA or intermediate (change “
caCert.pem
” to “intermediateCert.pem
” if you are in theintermediateCertificate
directory):openssl verify -partial_chain -CAfile caCert.pem deviceCertificates/deviceCert.pem
Creating the chain of certificates¶
To create a chain of certificates, navigate to the caCertificate
directory:
- If the CA certificate was created, which was used to sign the intermediate certificate and then the intermediate certificate was used to sign the device certificate, then create the chain of certificates using the command:
cat intermediateCertificate/deviceCertificates/deviceCert.pem intermediateCertificate/intermediateCert.pem caCert.pem > intermediateCertificate/deviceCertificates/deviceCertChain.pem
- If an intermediate certificate is not used, then use the command:
cat deviceCertificates/deviceCert.pem caCert.pem > deviceCertificates/deviceCertChain.pem
- If multiple intermediate certificates are being used between the CA certificate and the device certificate, then ensure to maintain the correct order during the chain creation. That is, every certificate has to be followed by the certificate, which it is signed by.
Creating keystore and truststore¶
- Navigate to the
deviceCertificates
directory with the device’s private key and the generated chain of certificates. If an intermediate certificate is being used between the CA certificate and the device certificate then it will be thecaCertificate/intermediateCertificate/deviceCertificates
path, otherwise it will becaCertificate/deviceCertificates
.
Create keystore using the generated chain of certificates and the private key of the device:openssl pkcs12 -export -name devicekeyentry -inkey deviceKey.pem -in deviceCertChain.pem -out deviceKeystore.pkcs12
- If the keystore must be converted to JKS format, then it is required to have the Java Keytool which is usually downloaded together with Java Development Kit:
keytool -importkeystore -srckeystore deviceKeystore.pkcs12 -srcstoretype PKCS12 -destkeystore deviceKeystore.jks -deststoretype JKS
- If the server certificate is not available, it can be made available by the command:
openssl s_client -showcerts -connect <mindsphere url>:<mqtt mutual ssl port (currently 8883, but that can be changed in the future)> | openssl x509 -outform PEM > serverCertificate.pem
- Now a truststore can be created, which will contain the server certificate. It has to be created with Java Keytool (openssl does not support creating truststore, so if the Java keytool is not used, then it is required to keep every trusted certificate in a separate pem file). Remember that the alias is the unique identifier for every keystore or truststore entry. It means that it is required to add a second trusted certificate to the same truststore and then change the alias from servercertificate in the command below to some other name:
- In PKCS12 format:
keytool -importcert -noprompt -keystore deviceTruststore.pkcs12 -alias servercertificate -file serverCertificate.pem
- In JKS format:
keytool -import -file serverCertificate.pem -alias servercertificate -keystore deviceTruststore.jks
- In PKCS12 format:
- Optionally, instead of creating a new file for the truststore, it is possible to add the trusted certificates to the created keystore and store everything in one file, which is not the recommended solution:
- If the keystore is in the PKCS12 format:
keytool -importcert -noprompt -keystore deviceKeystore.pkcs12 -alias servercertificate -file serverCertificate.pem
- If the keystore is in the JKS format:
keytool -import -file serverCertificate.pem -alias servercertificate -keystore deviceKeystore.jks
- If the keystore is in the PKCS12 format:
- Check the content of your keystore (or truststore) with the command:
keytool -list -v -keystore deviceKeystore.jks
Testing certificates with MQTT.fx client¶
- Generate a keystore and a truststore as described in Preparing Trusted Certificates if not already done.
- Upload the CA (or intermediate) certificate to the platform. This operation will add the uploaded certificate to the server’s truststore. It can be done in two ways, via User Interface and via REST.
Via User Interface¶
To add a certificate via User Interface, see Section Trusted certificates in MindConnect IoT Extension System Manual.
Via REST¶
To add a certificate via REST, proceed as follows:
-
Display the CA (or intermediate) certificate, which is required to upload to the MindConnect IoT Extension and copy its PEM value, which starts with
—–BEGIN CERTIFICATE—–
and ends with—–END CERTIFICATE—–
(including the hyphens). Remove new line symbols (\n
) if they were added automatically at the end of each line:openssl x509 -in caCert.pem -text
. -
Send it to the platform via POST request:
Required role: ROLE_TENANT_ADMIN POST /tenant/tenants/<TENANT_ID>/trusted-certificates Host: https://<TENANT_DOMAIN>/ Authorization: Basic <YOUR_AUTHENTICATION> Content-Type: application/json { "status" : "ENABLED", "name" : "certificateName", "autoRegistrationEnabled" : "true", "certInPemFormat" : "<CERT_PEM_VALUE>" }
-
Download and install the newest MQTT.fx client.
- In MQTT.fx, click “Extras” at the top and then “Edit Connection Profiles”.
- Insert the Insights Hub URL in the “Broker address” line.
- Insert the SSL port in the “Broker port” line.
- In the “Client ID” field, insert the common name of the device certificate.
- Select "SSL/TLS" as the authentication type.
- Click “Enable SSL/TLS”.
- Select “TLSv1.2 protocol”.
- Select “Self signed certificates in keystores”.
- In the “Keystore File” field, insert the path to the deviceTruststore file with either JKS or PKCS12 format.
- In the “Trusted Keystore Alias” field, insert “servercertificate” or a different value if you provided a different alias in step 3 above.
- In the “Trusted Keystore Password” field, insert the password, which is created during the deviceTruststore file creation.
- In the “Client Keystore” field, insert the path to the deviceKeystore file with either JKS or PKCS12 format.
- In the “Client Keystore Password” field, insert the password created during the deviceKeystore creation.
- In the “Client KeyPair Alias” field, insert “devicekeyentry” or a different value if you provided a different alias in the “-name” parameter during the keystore creation.
- In the “Client KeyPair Password” field, insert the password, which is created during the deviceKey.pem creation.
- Check the “PEM formatted” field.
- Save and close the settings.
- Select the edited profile and click connect.
The connection is successful, and the buttons “Disconnect”, “Publish” and “Subscribe” are active now. That is, the connection with the certificates works correctly. The connection settings should look like this:
Related Links¶
- General Information (Why Insights Hub, Demo, Request Access...)
- MindConnect Products
- MindConnect IoT Extension System Manual
- MindConnect IoT Extension Getting Started Manual
- MQTT.fx
- OpenSSL Toolkit
- Device integration using MQTT
Except where otherwise noted, content on this site is licensed under the Development License Agreement.