Thorsten Scherf
Identity Management & Platform Security

How to export a private key from NSSDB

I recently had an issue where I accidentally lost the private key for my webserver certificate. The webserver is running as part of a FreeIPA environment. Luckily in such a setup the LDAP-Server share the same certificate and key with the webserver. So all I had to do is to copy the private key from the LDAP-Server certificate database to the webserver configuration directory. Unfortunately it was not all that easy. While the webserver expects the key in a plain PEM file, the LDAP-Server has the key stored in a NSS database.

To list the certificates from the NSS database used by the LDAP-Server the following command can be used:

# certutil -d /etc/dirsrv/slapd-TESTRELM-TEST/ -L

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

TESTRELM.TEST IPA CA                                         CT,C,C
Server-Cert                                                  u,u,u

The same tool can be used to list private keys stored in the database:

# certutil -d /etc/dirsrv/slapd-TESTRELM-TEST/ -K -f /etc/dirsrv/slapd-TESTRELM-TEST/pwdfile.txt
certutil: Checking token "NSS Certificate DB" in slot "NSS User Private Key and Certificate Services"
< 0> rsa      7f6c9b997a8d54899c1cce7b447433d1aa06a64c   NSS Certificate DB:Server-Cert

The file /etc/dirsrv/slapd-TESTRELM-TEST/pwdfile.txt contains the password to unlock the database which is needed to get access to the private keys.

So next I wanted to export the private key that belongs to the certificate with the nickname Server-Cert. The tool pk12util can be used for this:

# pk12util -d /etc/dirsrv/slapd-TESTRELM-TEST/ -n Server-Cert -k /etc/dirsrv/slapd-TESTRELM-TEST/pwdfile.txt -o /tmp/server-cert.p12 
Enter password for PKCS12 file: 
Re-enter password: 
pk12util: PKCS12 EXPORT SUCCESSFUL

Here it’s useful again that the tools allows to specify a file that contains the password to get access to the key. additionally it’s possible to secure the output file with a password so that others don’t get access to the key.

It’s also easy to check the content of the pkcs12 file so verify the export was successful:

#  pk12util -l /tmp/server-cert.p12 -r -n "Server-Cert"
Enter password for PKCS12 file: 
Key(shrouded):
    Friendly Name: Server-Cert

    Encryption algorithm: PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC
        Parameters:
            Salt:
                f1:a8:4a:b6:f6:d0:47:28:ae:2a:91:d7:ea:68:9e:1a
            Iteration Count: 600000 (0x927c0)
Certificate    Friendly Name: TESTRELM.TEST IPA CA

Certificate    Friendly Name: Server-Cert

And finally I can now export the private key from the pkcs12 file and store it as PEM file so that the webserver can successfully start again:

# openssl pkcs12 -info -in /tmp/server-cert.p12 -nodes -nocerts -out /var/lib/ipa/private/httpd.key
Enter Import Password:
MAC: sha1, Iteration 600000
MAC length: 20, salt length: 16
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 600000
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 600000
Certificate bag
Certificate bag

Of course this all is just possible because the LDAP-Server and the webserver both share the same key.

ipa nss