Dcm4chee: Setting up TLS Encryption
Here we discuss how to set up TLS encryption in dcm4chee2.x for both the server and client. TLS encryption allows for secure communication between the two parties, one which is impervious to snoopers, interceptors and fakers.
In an upcoming article we will describe how to make TLS work with Weasis launched from dcm4chee, which comes with a few of its own gotchas.
Although the setup is relatively straightforward, it can be a bit difficult if you’ve never setup TLS before or a struggling with the concept. There are also a few dcm4chee specific gotchas along the way.
Let’s dive in!
TLS explained … really simplistically
Note: If you have a firm understanding of TLS you can skip this section, however, then you probably don’t need help going beyond the official docs for setting it up w/ dcm4chee.
To have a pain-free experience setting up TLS w/ dcm4chee, you need to understand a few basic things about TLS and how it’s setup in practice. For some reason, it’s rather difficult to find a simple explanation online.
TLS is a way for both client and server to communicate securely. In TLS, this basically means two things:
- The communication stream is encrypted and safe from snoopers.
- The client and server both trust each other’s identities and can verify said trust through some pre-established means.
In practice, the way this is achieved is that both client and server have their own two separate files that they refer to:
- A keystore, ie: keystore.jks (contains info for encrypting / decrypting the communication stream sent to / received from other party)
- A trust store, ie: trust.jks (contains info about whether I can trust that the other party is who they claim to be, ie: Google Inc, my home server, etc).
The truststore tells its owner who it trusts enough to communicate with, and it consists of a bunch of certificates, one belonging to each potential communication partner.
A certificate’s role is to provide a means to identify communication packets as coming from this partner, and is often issued by some large private entity (for a fee) which certifies that certificate X really does correspond to entity XYZ (ie: Google Inc.). However, self-signed certificates can be used as well and are perfectly fine for internal communication (ie: you’re running a client to talk to your own server).
Using the certificate, one can verify whether incoming packets are from who you think they are – the only way for an attacker to trick you otherwise, is if they somehow also get ahold of that third parties keystore (which should be guarded against with the proper precautions).
So if a client and server want to communicate via TLS each party needs to 1) have a certificate 2) have a copy of the other’s certificate in their truststore, ie:
- client_truststore.jks contains server.cert
- server_truststore.jks contains client.cert
Otherwise the communication simply won’t work, and in practice may fail without an especially useful error message.
Setting up TLS w/ dcm4chee
Now that we have a minimum understanding of TLS, setting it up with dcm4chee will be quite simple. We can basically follow the docs, except that we will be wanting to generate independent credentials for client and server (the docs, as of this writing, assign the same credentials to both client and server, which is not a very general use case).
The steps are as follows:
1. Using the jmx-console of your jboss install, set the following attributes in dcm4chee.archive:service=DcmServer:
SecurityProtocol = dicom-tls
And set following attributes in dcm4chee.archive:service=TLSConfig:
EnabledProtocols= SSLv2Hello,SSLv3,TLSv1 KeyStoreURL=resource:server_keystore.jks KeyStorePassword=yourpassword TrustStoreURL=resource:server_trust.jks TrustStorePassword=yourpassword
2. Generate the server-side keystore and truststore files, using the same password you specified in the TLSConfig service:
keytool -genkey -keyalg RSA -dname "CN=node1.yourorg.org OU=development O=yourorg L=YourLocation C=AT" --keystore server_keystore.jks -alias node1
3. Generate the client-side keystore and truststore files (using a separate client side password):
keytool -genkey -keyalg RSA -dname "CN=test_client.yourorg.org OU=development O=yourorg L=YourLocation C=AT" --keystore client_keystore.jks -alias test_client
Export the client’s certificate, and import it into the server’s truststore.
keytool -export -file test_client.cert -keystore client_keystore.jks -alias test_client
keytool -import -file test_client.cert -keystore server_trust.jks -alias test_client
Now export the server’s certificate, and import it into the client’s truststore.
keytool -export -file server.cert -keystore server_keystore.jks -alias node1
keytool -import -file server.cert -keystore client_trust.jks -alias node1
4. Copy the server-side key and truststore files into the dcm4chee installation directory:
cp server_keystore.jks DCM4CHEE_HOME/server/default/conf cp server_trust.jks DCM4CHEE_HOME/server/default/conf
5. Restart the dcm4chee server process
6. Test out your TLS config with a tls-enabled client test query using, say, dcmqr from the dcm4che toolkit:
dcmqr DCM4CHEE@:11112 -tls AES -truststore ./client_trust.jks -keystore ./client_keystore.jks -L CLIENTAET:9998 -keystorepw YOURKEYSTOREPWD -truststorepw YOURTRUSTSTOREPWD -no_ssl2
It should return a non-errorful response. Take note of the -no_ssl2 option – depending on your system you may need it to avoid an error response.
Note: The above has been tested on dcm4chee-2.18.x, no more no less :).