Home‎ > ‎Dabbles‎ > ‎RaspberryPi‎ > ‎

RaspberryPi 223 - Signing Client Certificates

posted Nov 29, 2015, 6:06 AM by Joshua S   [ updated Nov 29, 2015, 2:31 PM ]
This tutorial will sign a Client Certificate using an Intermediate Certificate Authority (CA) created by the RaspberryPi's builtin OpenSSL framework.  Client certificates are used to support authentication and authorization to a number of clients where as client certificates are used primarily for user authentication.  

To give credit where credit is due; this lesson is based heavily off of this lesson from others.  For a really good overview of the concepts behind CAs and PKI, check out this post.

With any of the Dabbles on this site, if you have questions, suggestions, or thoughts, please feel free to send me an eMail (I'm still working to figure out how to enable comments on Google Sites -- suggestions would be appreciated)!

Supply List:
  • RaspberryPi  The actual RaspberryPi hardware this will all be built around.  In this tutorial, a Raspberry Pi 2 is used and has a memory card with the Raspbian operating system pre-installed.
  • PuTTY SSH Client – PuTTY is a free and open-source terminal emulator, serial console and network file transfer application. It supports several network protocols, including SCP, SSH, Telnet, rlogin, and raw socket connection.  Other SSH tools can be used, but this tutorial will leverage PuTTY.
Prerequisites:

Project:
  • I know I said this guide was going to be comprehensive and not skip any steps, so what better way to start this off than by skipping steps.  I am not writing out instructions for the following (and illustrating from XKCD):
    • Buying a MicroSD Card
    • Buying a RaspberryPi 
    • Finding the IP Address of your Pi
      • This can be done in many ways, including on your router or using an IP scanner such as (AngryIP Scanner or NMAP) -- if there are requests from the "Contact Me" form; I'll look to create a tutorial for this.
    • Obtaining and installing PuTTY
https://xkcd.com/1343/
  • Using PuTTY (or the SSH client of your choice) enter the IP Address or DNS Name of the RaspberryPi.
  • If this is the first time you connect, you will get a warning that the RaspberryPi's host key is unknown.  Click "Accept" or "Connect Once" to proceed with the connection.
  • Once connected, log onto the Pi using the credentials you created.  If you have not defined your own credentials, you should, but these are the default credentials:
  • UserID:  pi 
  • Password:  raspberry
  • First things first, in the previous dabble, we created the directories for the intermediate Certificate Authority (CA).  Now, we need to create a server key.  
    • Note -- this is written from the perspective of a Certificate Authority.  Third parties can also issue their own certificate signing requests (CSR) using their own private keys for us to sign and issue a certificate, but that is a different process for a different dabble.  
    • Note -- while the CAs used 4096 bit keys, most server and client certificates use no larger than 2048 bit (many use 1024 bit) keys in the interest of balancing security with the performance of the TLS "handshake".  As a result, this dabble will use 2048 bit keys for the server and client certificates.
    • Note -- certificates can be issued with or without passwords.  Passwords do make the certificate much more secure, but they also introduce the need to enter the password before use.  As a result, often server certificates do not use passwords (you would need to re-enter the password each time you restart a webserver, for example), some client certificates focused on services such as LDAPS or authentication of an embedded device also do not use passwords, but passwords should be used for client certificates needed for authentication in services such as VPN to ensure the authorized user is presenting the certificate.  Inclusion of the -aes256 option determines if a password will be tied to the certificate.
sudo openssl genrsa -aes256 -out /root/ca/intermediate/VPN/private/vpn.client.key.pem 2048
<Client Password>
sudo chmod 400 /root/ca/intermediate/VPN/private/vpn.client.key.pem

  • With the key created, we need to generate a Certificate Signing Request (CSR) in order to create the actual certificate.  
    • Note -- based on the configuration we used earlier to create the intermediate CA, the CSR details don’t need to match the intermediate CA, but I like to keep everything matching as a best practice. 
    • Note -- for server certificates, the Common Name must be a fully qualified domain name (FQDN) such as vpn.academicdabbling.com, whereas for client certificates it can be any unique identifier such as a device name or eMail address. 
    • Note -- the Common Name can not be the same as either your root or intermediate certificate.
sudo openssl req -config /root/ca/intermediate/VPN/openssl.cnf -key /root/ca/intermediate/VPN/private/vpn.client.key.pem -new -sha256 -out /root/ca/intermediate/VPN/csr/vpn.client.csr.pem
<Client Password>
<Your CA / Organizational details>


  • Now, to convert our CSR to a certificate, we will use the intermediate CA to sign the CSR.  Since, the certificate is going to be used on a client, we will use the usr_cert extension. 
    • Note -- if the certificate were to be used for a server, we would use the server_cert extension instead. 
    • Note -- certificates are usually given a validity of one year.  This way, though they are publicly facing and at greater risk of compromise, the risk is limited to a one year period.  Consider -- the one year expiration requires the certificate to be reissued at the end of that period; thus may projects or small businesses will issue for a greater period of time despite the risk.
sudo openssl ca -config /root/ca/intermediate/VPN/openssl.cnf -extensions usr_cert -days 365 -notext -md sha256 -in /root/ca/intermediate/VPN/csr/vpn.client.csr.pem -out /root/ca/intermediate/VPN/certs/vpn.client.cert.pem
<Intermediate CA Password>
y
y
sudo chmod 444 /root/ca/intermediate/VPN/certs/vpn.client.cert.pem

  • Let's make sure the root CA registered the signature process.  To do this, we need to look in the index.txt file of the root CA using the cat command.  Review any entries to ensure our new intermediate CA is listed.
sudo cat /root/ca/intermediate/VPN/index.txt

  • Good -- we know the certificate was signed, now let's check that the details of the cert look correct using OpenSSL.  Validate the details to ensure they align with your inputs.  In particular, the Issuer should be the intermediate CA and the Subject should refer to the certificate itself.
sudo openssl x509 -noout -text -in /root/ca/intermediate/VPN/certs/vpn.client.cert.pem

  • OK -- now that we know the details look good, let's validate the intermediate CA cert against the root cert to ensure the chain of trust is intact.  If we get a response of "OK" we know everything worked.
sudo openssl verify -CAfile /root/ca/intermediate/VPN/certs/ca-chain.cert.pem /root/ca/intermediate/VPN/certs/vpn.client.cert.pem

    • If you are using this certificate with an application that requires Diffie-Hellman parameters, you need to add those to the certificate now.  This is optional as many services and applications do not require this.  You should have created a Diffie-Hellman parameter file when you created your intermediate Certificate Authority and it should follow the naming convention "dh<key size>.pem" (ex. dh2048.pem).  Issue the following command to add these parameters to your certificate.  Note, these commands were performed as root.
    sudo su root
    chmod 644 /root/ca/intermediate/VPN/certs/vpn.client.cert.pem
    cat /root/ca/intermediate/VPN/certs/dh2048.pem >> /root/ca/intermediate/VPN/certs/vpn.client.cert.pem
    chmod 444 /root/ca/intermediate/VPN/certs/vpn.client.cert.pem


    • OK, good.  Let's check our work -- if everything worked as planned, we'll see the Diffie-Hellman parameters appended to the bottom of the certificate.
    sudo cat /root/ca/intermediate/VPN/certs/vpn.client.cert.pem


  • You can now deploy the certificate to the client -- this process is unique to each client and application, but perhaps there will be future dabbles about this.  Ensure the following files are available to the client:
    • vpn.client.key.pem
    • vpn.client.cert.pem
  • Congratulations!  Your server certificate is now issued and ready to go!  
Comments