Skip to content

Instantly share code, notes, and snippets.

Last active Mar 30, 2020
What would you like to do?
Create openHAB (Jetty) keystore from OpenSSL certificate/key pair

Configure openHAB keystore to use our own TLS server certificates

1. Launch openHAB, and verify that the shipped cert is in effect

$ openssl s_client -connect localhost:8443
[lots of stuff truncated]
No client certificate CA names sent
SSL handshake has read 1614 bytes and written 296 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 52B1FD317C19B5067235A4FDF277B0AF5FFDF7AA760A431CC53B8C0C2CC796A7
    Master-Key: 8EEAA5595C7E46BEAFABC4CAE2797A704FD79754BB2BDBF3159CC42427E497C5B58522D7ED166A1A256D1189148EB93E
    Key-Arg   : None
    Start Time: 1387396401
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)

Result: yes: openHAB's default SSL/TLS cert is being used (

2. Create our own TLS certificates. We have

  • ca.crt the CA certificate in PEM format
  • server.crt the Server certificate in PEM format
  • server.key the Server key in PEM format

3. Shut down openHAB

4. Backup etc/keystore

5. Show content of keystore. Password is empty (hit enter; stupid keystore)

$ keytool -keystore etc/keystore -list -v
Alias name: mykey
Creation date: Jun 11, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 1
Owner:, OU=Unknown, O=openHAB, L=Unknown, ST=Unknown, C=Unknown
Issuer:, OU=Unknown, O=openHAB, L=Unknown, ST=Unknown, C=Unknown
Serial number: 2a06f6fc
Valid from: Tue Jun 11 22:02:35 CEST 2013 until: Fri Jun 09 22:02:35 CEST 2023
Certificate fingerprints:
	 MD5:  9D:D1:7E:E2:42:A7:62:BB:14:8E:3A:4A:88:67:C8:3D
	 SHA1: 34:32:A9:52:5B:C7:08:69:40:DE:A7:AD:E4:10:C9:1E:37:54:A5:4A
	 Signature algorithm name: SHA256withRSA
	 Version: 3


#1: ObjectId: Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: FC FA 42 F5 FD AF E2 C8   12 DE A5 D4 66 3B 58 E2  ..B.........f;X.
0010: 67 DC CE F4                                        g...

6. Create a PKCS#12 container file with ca.crt, server.crt and server.key

The password we're going to be asked for will encrypt the key and it protects the PKCS#12 container. The container we'll destroy in a moment, but the password we make a note of for later.

$ cat ca.crt server.crt > chain.pem

$ openssl pkcs12 -export -inkey server.key -in chain.pem -out /tmp/oh.p12
Enter Export Password:
Verifying - Enter Export Password:

$ rm chain.pem
$ ls -l oh.p12
-rw-r--r--  1 jpm  staff  4061 Dec 18 21:01 oh.p12

7. Import PKCS#12 container into keystore

$ rm etc/keystore		# yup. You made a backup, didn't you?!

$ keytool -importkeystore -srckeystore /tmp/oh.p12 -srcstoretype PKCS12 -destkeystore etc/keystore
Enter destination keystore password:		<-- 6 chars "xxxxxx"; MAKE A NOTE
Re-enter new password:
Enter source keystore password:			<-- password from step 6 above
Entry for alias 1 successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

$ rm /tmp/oh.p12

8. Verify new openHAB keystore contains our certificates

$ keytool -keystore etc/keystore -list -v
Enter keystore password:		<-- enter blank password ?!?!?!
Alias name: 1
Creation date: Dec 18, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 2
Issuer:,, CN=An MQTT broker
Serial number: a7de80faa9356517

9. Create passwords for jetty.xml

Actually we need two passwords, same command, different argument

  1. password for key from step 6 (this OBF: string goes in KeyPassword)
  2. password for keystore from step 7 (this OBF: string goes in Password)
$ java -cp server/plugins/org.eclipse.jetty.util_8.1.3.v20120522.jar xxxxxx

Repeat for second password.

10. in etc/jetty.xml set password.

Search for SslSelectChannelConnector and copy the OBF string from step 9 into

                        <New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
                                <Set name="port"><Property name="jetty.port.ssl" /></Set>
                                <!-- <Set name="Host"></Set> JPM: bind to loopback -->
                                <Set name="maxIdleTime">30000</Set>
                                <Set name="Acceptors">2</Set>
                                <Set name="AcceptQueueSize">100</Set>
                                <Set name="Keystore"><Property name="jetty.home" default="." />/etc/keystore</Set>
                                <Set name="Password">OBF:20lb20lb20lb20lb20lb20lb</Set>
                                <Set name="KeyPassword">OBF:010101010101010101010101</Set>

11. Launch openHAB

Verify the console, check that no errors regarding "tampering" of keystore arise.

12. Connect to openHAB and verify it's using our server certificates

$ openssl s_client -connect localhost:8443
issuer=/CN=An MQTT broker/
Copy link

jpmens commented Dec 18, 2013

openssl s_client -connect -CAfile ca.crt -tls1

Copy link

jpmens commented Dec 19, 2013

If s_client reports a connection error (or rather no certificates are shown), force -ssl3.
See this /via Ben.

Copy link

ludodoucet commented Jun 16, 2015

I generate a server.crt and a server.key with this method: , where can I find or how generate "ca.crt the CA certificate in PEM format"?

Copy link

papadi commented Feb 8, 2017

Thanks, but I have the feeling that this doc is a bit obsolete. Correct me if I'm wrong.

  • I couldn't find the file anywhere org.eclipse.jetty.util_8.1.3.v20120522.jar. I googled it and downloaded it to pass step 9.
  • On Synology installation I have userdata/etc/jetty.xml and runtime/etc/jetty.xml. Neither of the two contain a SslSelectChannelConnector section.

Copy link

klaernie commented Sep 27, 2017

@jpmens: feel free to take a look at my fork, I found a way to avoid modifying the stock keystore and jetty.xml by creating a new keystore under /etc/openhab2 and modifying JAVA_EXTRA_VARS in /etc/default/openhab2.

Thanks for your work in writing this up, it helped a lot to find my own way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment