Making a Ghidra server use a custom SSL certificate

Written by Ash on Filed in sysadmin Tags: tips sre ghidra

Over the past little while I’ve helped sysadmin a small Ghidra server for the 4TU staff team. After Fedora changed their crypto policies in version 33, the TLS certificate broke and my connections started failing. One of the things I’ve noticed is a lack of documentation for the Ghidra server, so I figured I may as well write down how I ended up making it work for our system.

An error dialog from Ghidra, showing that "cerfificates do not conform to algorithm constraints" - 128.6 KiB image

The key issue here is that on its own, the Ghidra server (9.1.2 at the time of writing) will generate a self-signed SSL certificate, using a SHA1/RSA 2048-bit signature. Fedora 33 added their “strong crypto phase 2” setup, which rejects anything less than SHA256 with 2048-bit RSA across the board (3072-bit if you want to be futureproof). I’m impressed that they extend these settings into the JVM!

Most results I could for this kind of error online seem to boil down to “tell the JVM to accept weaker cryptography” which, while it does work, isn’t exactly a good long-term solution. Ghidra’s selection of signature algorithm is, somewhat unfortunately, hard-coded, so we can’t configure it to generate more helpful certificates on its own, either. Thus, the approach I took here was to externally generate a certificate and get Ghidra to use it for SSL instead of its own.

Enough stalling, let’s get into it! First I made a self-signed certificate in p12 format, shamelessly copying some commands from IBM:

# make a 4096-bit key. Not sure how to set the SHA version, but it defaulted to 256
# Note the long expiry
# Ghidra's own certs have the CN set to "GhidraServer"
# Not sure if required but I did the same
openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -days 1826 -out certificate.pem
# Convert to p12. I set a password, remember it!
openssl pkcs12 -inkey key.pem -in certificate.pem -export -out certificate.p12

Pretty standard so far - note that I set a password on the p12 bundle. I’m not strictly sure it’s needed since we’ll also set one in the next step, but I just used the same one across all of it and things seem to work. Speaking of, the next step is the somewhat secret sauce that the Ghidra server manual only vaugely hints at: using keytool. Being Java, Ghidra reads certificates from a custom file format, so we need to perform another conversion step.

# Will ask for the p12 password and then a password for the new JKS file
keytool -importkeystore -srckeystore certificate.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype JKS

We then add the final keystore.jks file to our Ghidra configuration, along with the password you gave the tool. Most of it should already be in the template config:

# If Ghidra clients must authenticate the server, the server will need to install
# a server key/certificate in a secure location (e.g., /etc/pki/...) 
# and specify the location and password via the properties below.
# Be sure to properly set permissions on the Ghidra installation and this file
# if using these settings.
wrapper.java.additional.5=-Dghidra.keystore=/home/ghidra/keystore.jks
wrapper.java.additional.6=-Dghidra.password=mysupersecretpassword

After restarting the server, mine came up with a proper SSL certificate! The only thing to note is that Ghidra is not responsible for generating this certificate, so I have no idea what will happen when it expires. I’m planning on just swapping it out for a fresh one before that happens. Despite the implications of the manual, clients do not “authenticate the server” using this method - presumably they would need to be told to do so explicitly, and given a CA to verify against - so the self-signed cert works fine in this case.

Hope this proved helpful to some extent; and it keeps working well enough until Ghidra adopts a more robust method of handling SSL. Personally, I’d like to reverse-proxy it, though I suppose since ours is already behind a VPN it’s overkill anyway~

I've disabled comments until I can come up with a good, privacy-respecting way to implement them.