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 CA UI:
- Set Enable Key Recovery in System Configuration.
- Create a new End Entity Profile and select use for Key Recoverable.
- Add users with this End Entity Profile. Use a keystore type other than User Generated, for example P12, and select Key Recoverable.
- Enroll the user with Create keystore in RA 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.
Archived keys are stored as a password protected PKCS#12 and are further encrypted using an ephemeral AES256 symmetric key, which in turn is encrypted using the CA's designated encryption key.
For encryption, only the RSA and Elliptic Curve Cofactor Diffie Hellman (ECCDH) suites are supported. In the case of ECCDH, only ciphers with a cofactor of 1 may be used, limiting curve choices to the following: P-224, P-256, P384, P-521, K-233, K-283, K-409, K-571, B-233, B-283, B-409, and B-571, see NIST's internet draft on ECC CDH Component Capabilities JSON Values.
For architectural reasons, when using key archival the end entity key cipher must match that of the signing and encryption keys, in other words only EC end entity keys can be archived by an EC CA (though they can have different curves), and only RSA end entity keys can be archived by an RSA CA.
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 RA GUI in your browser.
Using the RA UI:
- RA UI → Search > Certificates → View (for a specific certificate).
- RA UI → Recover Key → Enter new enrollment code → Confirm request.
- RA UI → Enroll → Use Username → Enter username and password → Fetch P12 / JKS / PEM.
- Optionally, Enroll → Request ID can be used if the operation requires approval.
Using the WS API:
or, combining it into a single command:
You can use auto-generated passwords for end entities, so when enrolling for a new certificate/keystore, and recovering an old keystore, the user is sent an auto-generated password through email.
To enable auto-generated passwords:
- Enable the Auto-generated option under Edit End Entity Profile → → Auto-generated.
- Add a notification for STATUSNEW and STATUSKEYRECOVERY under Edit End Entity Profile → Notifications → Notification Events.
Note that you must ensure that e-mail notifications work in order to use the auto-generated passwords feature.
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) .
bin/ejbca.sh ra keyrecovernewest, the recover key option in the CA UI, 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 CA UI.
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.
Importing Key Recovery Data from External Sources
It is possible to import key recovery data from an external source, something that can be very useful when migrating to EJBCA from another PKI product.
Importing key recovery data is done from the command line, which provides online help.
bin/ejbca.sh ra keyrecoveryimport --help