This is the third part of a ThingBerry related blog post series.



ThingBerry is ThingWorx installed on a RaspBerry Pi, which can be used for portable demonstrations without the need of utilizing e.g. customer networks. Instead the ThingBerry provides its own custom WIFI hotspot and allows Things to connect and send / receive demo data on a small scale.


In this particual blog post we'll discuss on how to setup the ThingBerry for encrypted communication and trust via certificates. We will create a custom Root and Intermediate Certificate Authority as well as a server specific certificate.


More information on the theory of Trust & Encryption can be found here: Trust & Encryption - Theory


As the ThingBerry is a highly unsupported environment for ThingWorx, please see this blog post for all related warnings.


Preparing the environment


To get started and keep all the working materials safe and secure within the scope of the pi user account, let's start creating a workspace directory and then install the openssl package


cd ~
mkdir certs
chmod 700 certs
cd certs


sudo apt-get install openssl


Troubleshooting Tips




To look at a specific certificate use the keytool and specify the .crt file to look at


keytool -printcert -file rootca.crt


This will show information on the certificate's configuration, such as signing authority or validity.




It's important, that the Chain of Trust follows a timely fashion.

The Root CA has the longest expiration date. Within its validity the Intermediate CA must be valid. The server specific certificate must be valid in the timeframe of the Intermediate CA validity.


As the validity is calculated based on seconds of the current (signing) action, I'm using valid days of


  • Root CA 999 days
  • Intermediate CA 888 days
  • Server specific certificate 777 days


Any other times, that make sense can be used, as long as the time constraints are followed.

Otherwise the certificate will not be recognized as valid and will therefore not be trusted.


Creating a Chain of Trust


For this example we'll create a Root and Intermediate Certificate Authority (CA) as well as the server specific certificate. In a first step we can create all of the required keys.


openssl genrsa -des3 -out rootca.key 4096
openssl genrsa -out intermediateca.key 4096
openssl genrsa -out server.key 4096


The -des3 option for the rootca will store a password and encrypt it within the key for more secure access.

This tightens up security, so that the key for the rootca is not easily corrupted or exposed.


Root Certificate Authority


Having the keys, we now create the Root CA itself


openssl req -new -x509 -sha256 -days 999 -key rootca.key -reqexts v3_req -extensions v3_ca -out rootca.crt


Enter the information, starting with the password for the Root CA key.

Use a easy to identify name for the Common Name (CN), e.g. "My Root CA"


Intermediate Certificate Authority


As the Intermediate CA needs to be signed / approved by the Root CA, we need a Certficiate Signing Request (CSR)


openssl req -new -key intermediateca.key -reqexts v3_req -extensions v3_ca -out intermediateca.csr


The v3_ca extension will mark this certificate as CA itself.

This means that we can use the intermediate CA to sign other certificates as well.


The CSR will be signed with the Root CA's key and certificate.

For this the CSR must be sent to the whoever own the Root CA.

In our case, we're the owner ourselves and have everything in the same directory, so no need to send it off to Let's Encrypt, Google or VeriSign.


For signing the Intermediate CA as an actual CA, the Root CA must have a specific configuration to allow the v3_ca extension. This needs to be created via


nano v3_ca.ext


Into this new file, copy & paste the following:


basicConstraints        = CA:TRUE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer:always
keyUsage                = cRLSign, dataEncipherment, digitalSignature, keyCertSign, keyEncipherment, nonRepudiation


Save and exit.


Finally, the Root CA is signing the Intermediate CA, using the v3_ca extension via:


openssl x509 -req -in intermediateca.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -CAserial intermediateca.srl -extfile v3_ca.ext -days 888 -sha256 -out intermediateca.crt


Certificate Authority Chain


Having now two CAs, they need to be chained together.

This is required for later to create the keystore used in Tomcat.


Creating the Chain is probably the easiest part of this blog:


cat intermediateca.crt rootca.crt > cachain.crt


Server Specific Certificate


The server specific certificate has to be signed and obtained by the Intermediate CA; for this a CSR is required.


openssl req -new -key server.key -out server.csr


The request is then signed with the Intermediate CA's key and certificate.

For commerical certificates this signing process will be done by publicly trusted CAs, like Let's Encrypt, VeriSign or Google.

In our case, we're the Intermediate CA ourselves and can sign the CSR.


openssl x509 -req -in server.csr -CA intermediateca.crt -CAkey intermediateca.key -CAcreateserial -CAserial server.srl -days 777 -sha256 -out server.crt


Creating Keystores


For the keystore as used in Tomcat we need the CA Chain as well as the server specific certificate and the corresponding key.

To generate a keystore that can be used in Tomcat, we first need to create a PKCS12 type keystore with openssl


openssl pkcs12 -export -certfile cachain.crt -in server.crt -inkey server.key -out server.p12


This PKCS12 keystore can now be transformed into a JKS keystore, by importing the PKCS12 information into a new JKS keystore


keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS


Important: the passwords for the PKCS12 keystore and the JKS keystore must match!

Tomcat requires those passwords to be same - in case they are different, the configuration will not work and ThingWorx cannot be accessed through a secure connection.


Configuring ThingWorx


For ThingWorx, only the keystore is required.

It can be copied over e.g. to certificates area in the storage directory.


sudo cp keystore.jks /thingworx/storage/certificates
sudo chmod 640 /thingworx/storage/certificates/keystore.jks
sudo chown tomcat:tomcat /thingworx/storage/certificates/keystore.jks


To enable it, Tomcat's server.xml needs to be updated.


sudo nano $CATALINA_HOME/conf/server.xml


Find the connector for port 80 and add a new connector after the port 80 connector:


<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" connectionTimeout="20000"  redirectPort="8443"
           SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLSv1.2" enableLookups="false"
           keystoreFile="/thingworx/storage/certificates/keystore.jks" keystorePass="<keystorePass>" />


Don't forget to update the password.


Stop Tomcat


sudo service tomcat stop


Ensure Tomcat is actually down with


ps -ef | grep tomcat


If it's still running, just sudo kill it and start Tomcat again to activate the new configuration


sudo service tomcat start


And now?



ThingWorx is now running on your ThingBerry using a secure channel.


Access it via https://<thingberry>/Thingworx

As HTTPS is automatically using port 443, you will automatically connect to the port configured in the server.xml


Classic HTTP connections on port 80 can still be used.


For more information about setting up ThingWorx with (self-signed) certificates also see https://support.ptc.com/appserver/cs/view/solution.jsp?n=CS193947 - there's also a note on forwarding all HTTP traffic to HTTPS.


See also https://support.ptc.com/appserver/cs/view/solution.jsp?n=CS246292 for more information about using specific SSL protocols or cipher suites.