Key Recovery

Key Recovery can be used to re-use or restore a users private key. Key recovery means that server generated keys (and the certificate) of a user is stored, encrypted, in the CAs database. The purpose of this is to be able to recover an encryption key if the user loses the key. Without possibility of key recovery encrypted data will be lost forever if the encryption key is lost. Key recovery should only be used for encryption keys and not authentication or signature keys, where this need for recovery does not exist.

To enable key recovery using the Admin GUI:

  1. Set Enable Key Recovery in System Configuration.
  2. Create a new End Entity Profile and select use for Key Recoverable.
  3. Add users with this End Entity Profile. Use a keystore type other than User Generated, for example P12, and select Key Recoverable.
  4. Enroll the user with Create keystore in Public Web. A private and public key pair is now generated by the CA, encrypted and stored in CA database (KeyRecoveryData table).

Note that key recovery cannot be used with 'user generated' keys since the CA does not have access to the private key in this case, and can thus not store it.

Generate new Certificate

The following is an example of a sequence of commands used to generate a new certificate for a user using the same key pair, if the key and certificate was generated key recoverable as described above:

  • Mark the generated certificate for keyrecovery:
bin/ejbca.sh ra keyrecovernewest <username>
  • Set clear text password for Batch session to use:
bin/ejbca.sh ra setclearpwd <username> <userpass>
  • Reissue the certificate:
bin/ejbca.sh batch <username>

You can also generate a new certificate using the Admin GUI and Public Web or the RA GUI in your browser.

Using the Admin GUI and Public Web:

  • Admin GUI > List/Edit End Entities > View_Certificates for user > Recover Key and click Close.
  • Admin GUI > List/Edit End Entities > Edit_End_Entity for user > Enter new password for user and Save (user status should now be 'Key Recovery')
  • Public Web > Create Keystore > Enter username and password >Fetch the keystore.

Using the RA GUI:

  • RA GUI > Search > Certificates > View (for a specific certificate).
  • RA GUI > Recover Key >Enter new enrollment code > Confirm request.
  • RA GUI > Enroll > Use Username > Enter username and password > Fetch P12 / JKS / PEM.
  • Optionally, Enroll > Request ID can be used if the operation requires approval.

Local Key Generation

In systems with distributed RA's, using key recovery, it might be desired to store the key pairs used for recovery in a database belonging to another instance than the CA. With local key generation, the keys are stored in the RA's database and are encrypted with a crypto token (e.g. from a HSM) in the RA, so the key material is inaccessible to the operators of the CA (provided that they are restricted from logging in to the RA). The certificates and end-entities, however, remain stored in the CA and can be managed (e.g. revoked) from there.

In order to activate local key generation, the steps below are to be followed (this is performed on the RA which should keep the key recovery data):

  • Under System Configuration, set Enable Key Recovery and Force Local Key Generation.
  • Select the crypto token to be used for encryption of the key pairs (key recovery data).
  • Select the desired key for encryption.

Recovery data entries belonging to certificates enrolled before local key generation was enabled will remain in their initial database. Enabling local key generation doesn't change the way key recovery is performed by an administrator, nor the work flow of approvals, or access rules required. Keep in mind that the role handling the peer connector requires (at least) access to the same set of rules as the administrator of the external RA (for example to perform a key recovery). Since this feature intends to keep key material inaccessible from the CA by generating and storing the key pair on the local instance, it is not possible to use local key generation in combination with auto generated end entity passwords (generated by the CA) .

Technical Details

The operation bin/ejbca.sh ra keyrecovernewest, the recover key option in the Admin GUI, and the keyRecoverNewest in the WS API all marks the user/certificate for key recovery. This means that the next time you make a call to generate a keystore (p12/jks/pem) for the user the CA will get the private key, held encrypted in the recovery database, and the existing user certificate or a new certificate, and create a keystore for the user with this old key pair. The actual recovery would then happen when you make a call to i.e. pkcs12Req in the WS API, or if keystore type is P12, JKS or PEM in the Admin GUI.

The keys are stored in the database in the table KeyRecoveryData. The data is stored encrypted in a CMS message, as a serialized Java KeyPair. The certificate is not stored in KeyRecoveryData, but only in CertificateData. The encryption key used for the CMS message encryption is the issuing CAs 'keyEncryptKey', and can thus be a key on the HSM. The actual CMS data encryption is performed with AES256_CBC, using a random generated AES key (for this specific CM message). The AES key is wrapped using the RSA key in keyEncryptKey. This is fully according to the best practices, open, stable, CMS standard.

There are additional columns in the KeyRecoveryData table enabling change of the keyEncryptKey of the issuing CA. The columns cryptoTokenId and keyAlias gives an exact pointer to the Crypto Token, and specific key, used to encrypt the data. When decrypting data this specific key, with this alias, on the CAs Crypto Token, is first tried, and only if that fails the CAs 'keyEncryptKey' is tried. In addition, the public Key Id (as also exists in CertificateData) of the public key used to encrypt the data is stored in the column publicKeyId. This means that even if keys changed it is possible to identify the exact public key used to decrypt the data.

Similarly the column serialNumber column of the table KeyRecoveryData matches the column serialNumber in the table CertificateData.