EJBCA supports ECDSA signature keys in addition to RSA. You can create a CA using ECDSA keys both using the Admin GUI and the CLI (bin/ejbca.sh ca init).
This section provides information on ECDSA Keys and Signatures in the following sections:
Generated Keys and Certificates
When generating a CA in EJBCA, up to three keys and certificates are generated:
A CA signing keypair and certificate
An encryption keypair, used for encrypting key recovery information
An OCSP signer keypair and certificate
When using ECDSA keys, the CA signing keypair and the OCSP signer keypair will be the ECDSA keytype you select when creating the CA. The CA signing and OCSP signing certificate will be signed using your selected signature algorithm. The encryption keypair will always be RSA, using 1024 or 2048 bit key length. It uses the key length set in the Admin GUI or 2048 bit by default using the CLI.
Using ECDSA with an HSM
Note that the keyEncryptKey cannot be ECDSA, but should be an RSA key. Your HSM must support both ECDSA and RSA keys. You can use PKCS11HSMKeyTool from the clientToolBox to generate keys and certificate requests from an HSM. For more information, see the section about HSM property parameters.
Using named Brainpool curves in Java PKCS#11
Until recently, OracleJDK/OpenJDK did not have named curve definitions for the Brainpool curves. This functionality is available in later revisions of Java, such as late Java 8 and Java 11 releases. For older releases, Enterprise users can get a compiled patch together with an installation script for Debian-based operating systems from PrimeKey.
Brainpool should work on all HSMs that have named curve support for Brainpool. It has been tested on SafeNet Luna SA and Utimaco CryptoServer. SafeNet ProtectServer supports Brainpool but not using named curves, see below for brainpool support on ProtectServer using custom domain parameters.
You can create and use CAs with brainpool curves in the HSM. Example clientToolBox commands to generate a key:
./ejbcaClientToolBox.sh PKCS11HSMKeyTool generate /usr/lunasa/lib/libCryptoki2_64.so brainpoolP160r1 keyAliasBp160 1
./ejbcaClientToolBox.sh PKCS11HSMKeyTool test /usr/lunasa/lib/libCryptoki2_64.so 1
./ejbcaClientToolBox.sh PKCS11HSMKeyTool generate /etc/utimaco/libcs2_pkcs11.so brainpoolP160r1 keyAliasBp160 1
./ejbcaClientToolBox.sh PKCS11HSMKeyTool test /etc/utimaco/libcs2_pkcs11.so 1
Using SHA224WithECDSA in Java PKCS#11
OracleJDK/OpenJDK did not have support for SHA224WithECDSA in the PKCS#11 provider until recently. This functionality is available in later revisions of Java, such as late Java 8 and Java 11 releases. For older releases, Enterprise users can get a compiled patch together with an installation script for Debian-based operating systems from PrimeKey.
It should work on all HSMs that have support for SHA224WithECDSA.
Issue with explicit parameters in Java
In order to use elliptic curves with explicit parameters (as opposed to the standard named curves), you need to apply a patch to the file ECParameters.java.
Download the JDK source code and locate the file sun/security/ec/ECParameters.java.
Starting at line 210 there is code for handling of non-named curve EC parameters. Remove the Exception thrown in line 208 and enable the code that is commented out.
Compile the class by running 'javac *.java' in the directory where the file is located.
Replace the existing sun/security/ec/ECParameters.class file in jre/lib/rt.jar with your patched and compiled version.
Using Brainpool ECC with SafeNet ProtectServer Gold HSM
The following instructions were contributed by DGBK, Netherlands and apply for using Brainpool curves with the SafeNet ProtectServer Gold HSM. Note that ProtectServer needs explicit parameters for the Brainpool curves. Also, when using explicit parameters (and using the Sun PKCS#11 provider), you cannot use the EJBCA tools to generate keys, but have to use the HSM vendors tools.
Before generating domain parameters and keys, first apply the patch for explicit parameters, as described above.
Note that the following commands apply for ProtectServer Gold software version 3.33, firmware version 2.07.
Create domain parameters file brainpoolP160r1.txt from ptk_c_administration_manual_rev-c.pdf, Appendix G, Sample EC Domain Parameter Files. Note that you must add "cofactor=01" last in the parameters file, the cofactor is always one (in the spec document) for brainpool curves (cofactor=1 does not work, it has to be 01).
Configure the HSM to accept custom domain parameters (E flag):
Import the domain parameters to the HSM:
/ctkmu idp -s 1 -t ec -n brainpoolP160r1 brainpoolP160r1.txt
Generate keys and a (dummy) certificate. The dummy certificate is needed for the java PKCS#11 provider, the DN does not matter.
./ctcert c -k -l bpkey -tec -s1 -CbrainpoolP160r1 -d30y
Test the keys with:
./ejbcaClientToolBox.sh PKCS11HSMKeyTool test /opt/PTK/lib/libcryptoki.so 1
Start EJBCA and create a new CA with CAToken Properties:
ECC named curves vs explicit parameters
Normally, you want to generate requests and certificates using named curves encoded in certificates and requests, this is what IETF recommends. In some cases you need to generate the request and certificate with explicit parameters instead, this is for instance mandated by ICAO for usage in CSCA's and DS's for ePassports.
When generating requests with clientToolBox PKCS11HSMKeyTool certreq you can specify a flag to use explicit parameters instead of named curves. Named curves is the default.
When creating CAs with ejbca.sh ca init you can specify a flag to use explicit parameters instead of named curves. Named curves is the default.
When EJBCA issues certificate with public keys from certificate requests (csr's) the key in the certificate will be the same as in the csr. If the csr uses explicit parameters, so will the issued certificate.
If you generate a CA with explicit ECC parameters in the CA certificate you will not be able to run commands like 'ejbca.sh ca listcas' because Java only supports named curves when serializing certificates. You can resolve this by adding the BC provider as the first provider:
$ sudo vi /etc/java-7-openjdk/security/java.security
(renumber the ones below)
After editing this (make sure you edit the right file) you need to restart JBoss.
EJBCA supports the curves that BouncyCastle supports, including named curves from Nist, SEC and X9.62. New curves may be supported without this list being updated, give it a try. For more information about ECDSA curves, refer to the Bouncycastle wiki.
Note that EJBCA does not support/allow EC keys less than 224 bits long. Shorter curves are noted below for reference only.
X9.62 provides 3 alternatives for the parameters that can be found in an EC public key. One of these is named implicitlyCA and indicates that the parameters are defined else where, implicit in the name of the certification authority (CA) that issued the key. In this situation the actual parameters appear in the ASN.1 encoding of the key as a DER encoded NULL. As the definition says, when the key is used, the parameters will have to come from elsewhere. In EJBCA the parameters are configured in conf/cesecore.properties.
When creating a new CA using the implicitlyCA facility, you first configure your curve parameters in conf/cesecore.properties and issue commands:
After restarting the application server you can now create a new CA using the name implicitlyCA instead of a curve name as keyspec in the Admin GUI or CLI. The CA certificate will now be created with the NULL encoding of the public key.
When issuing client certificates where the client public key uses implicitlyCA, you must allow key length 0 in the certificate profile, because EJBCA can not read the key length, since the parameters are defined elsewhere.
See Bouncycastle wiki for more information about the implicitlyCA facility.
The curve parameters in conf/cesecore.parameters are configured in Bouncycastle using the following code:
ECCurve curve = new ECCurve.Fp(
new BigInteger(ecdsa.implicitlyca.q), // q
new BigInteger(ecdsa.implicitlyca.a, 16), // a
new BigInteger(ecdsa.implicitlyca.b, 16)); // b
org.bouncycastle.jce.spec.ECParameterSpec implicitSpec = new org.bouncycastle.jce.spec.ECParameterSpec(
curve.decodePoint(Hex.decode(ecdsa.implicitlyca.g)), // G
new BigInteger(ecdsa.implicitlyca.n)); // n
ConfigurableProvider config = (ConfigurableProvider)Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
Creating client certificates
You can also issue normal requests for client certificates using ECDSA keys.
All certificates signed by an ECDSA CA will naturally use ECDSA signatures, regardless if the client keys are RSA or ECDSA.
When batch generating client keys using the CLI command 'bin/ejbca.sh batch' you configure the type of client keys that will be generated in the file conf/batchtool.properties. The possible parameters are explained there. If using the implicitlyCA facility the same parameters as configured for the ca in conf/cesecore.properties are used.
When using the implicitlyCA mode only one set of curve parameters can be set for the whole EJBCA instance. This means that if you have several CAs using ECDSA with implicitlyCA, they will all use the same curve parameters. You can mix implicitlyCA with named curves according to your liking.