Yubikey & Raspberry Pi based 2-tier CA with step-ca

Table of Contents


Back when I set up the current iteration of my home network in 2018, I decided I wanted an internal CA, and that I wanted things to be simple. After a bit of looking around, I settled for XCA (https://hohnstaedt.de/xca/index.php) and got it running in a Debian Buster VM.

I ended up with a well working internal CA, fully manual, using RSA 4096 keys.

As of today, I still stand by this choice and still consider XCA to be a reasonably good choice for these needs. However, I was unsatisfied by this solution:

  • XCA is a graphical application, and I wanted to go headless.
  • I wanted to move to Elliptic Curve based certificates and hardware tokens for private keys storage. The bugtracker of XCA shows this scenario is not working well with latest version of XCA

At about the same time, I stumbled upon this blog post about the open source step-ca software component doing that. I also wanted to move my root CA away from a VM to a separate physical host, having just SubCA’s in VM’s for dedicated uses.

Implementing step-ca

I had a Yubikey 4 and a Raspberry Pi 3 lying around, so I decided to give it a shot over Ubuntu 20.04 arm64. After some fooling around, I got it to work.

Instead of just a copy-paste of the developer’s blog post, I decided to just highlight what is incorrect/suboptimal:

  • The golang-go package from Ubuntu 20.04 is fine and be used instead of building up go from the ground up. When working on a Raspberry Pi, that does matter a lot.
  • The PIV tool from Yubikey is obsolete and does not work anymore. Instead, the ykman command from the yubikey-manager package must be used, from the same Yubico repo. The command become, for example, ykman piv import-certificate 9a /mnt/ca/certs/root_ca.crt.
  • I don’t really believe in the whole write the private key on the USB stick directly thing. Anyway, it goes through unencrypted in the RAM of Raspberry Pi and is written encrypted with the password you set during generation. If your threat model includes this problem, you should really be generating the private key directly on a hardware token, not using some software on the Raspberry Pi.


My plans include a 3-tier CA: having a Root CA and Intermediate CA living on my RPI, that would generate some SubCA’s for my uses on my network.

This is not possible as of now, unless I’ve missed something:

  • The proposed way relies on using the step certificate command, which does not support interacting with the Yubikey.
  • I couldn’t figure out a way to get a CSR signed as a SubCA using the step ca command with the JWT approach.

I decided to settle for having the private keys living on the RPI, but I kept step-ca in the hopes that I can one day move to having them live on the Yubikey. After all, the PIV support is very recent in step-ca and things can evolve for the better.

Add a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.