EC keys and operations
The hardware JCE implementation (IBMJCECCA) extends the EC keys that are available in the software JCE implementation.
Keys
- An EC key pair that is already stored in the CCA key storage area. The key objects contain the
CCA key storage area label for the keys.The following example illustrates creating EC key objects for a key pair that is already stored in the CCA key storage area with the label "MYEC.KEYPAIR", then deleting the CCA key storage area entry:
// create key objects for an existing CCA key storage area entry // (No checking is done to verify that the entry exists.) // KeyFactory rsaKeyFactory = KeyFactory.getInstance("EC", "IBMJCECCA"); KeyLabelKeySpec spec = new KeyLabelKeySpec("MYEC.KEYPAIR"); PublicKey pubKey = ecKeyFactory.generatePublic(spec); PrivateKey privKey = ecKeyFactory.generatePrivate(spec); // delete the entry from the CCA key storage area // (An exception is thrown if the CCA key storage area entry does not exist.) // ((ECPrivateHWKey)privKey).deletePKDSEntry(); // // Note that, in this example, the Java key objects still // exist, but the CCA key storage area entry they represent has been deleted. // Any attempt to use the objects "pubKey" or "privKey" will // cause an exception containing a hardware return code and // reason code. //
- An EC key pair that is generated by an IBMJCECCA call to the underlying hardware, then stored in
the CCA key storage area. The key objects contain the CCA key storage area label for the keys.The following example illustrates generating an EC key pair that is stored in the CCA key storage area with an automatically generated label and creating key objects that contain the label for the CCA key storage area entry.
The following example illustrates generating an EC key pair that is stored in the CCA key storage area with the label "ANEC.KEYPAIR" and creating key objects that contain the label for the CCA key storage area entry:// create a new CCA key storage area entry and key objects to represent it. // AlgorithmParameterSpec spec = new ECHWKeyParameterSpec(256, KeyHWAttributeValues.PKDS, KeyHWAttributeValues.KEYMANAGEMENT); KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "IBMJCECCA"); generator.initialize(spec); KeyPair keyPair = generator.generateKeyPair(); PublicKey pubKey = keyPair.getPublic(); PrivateKey privKey = keyPair.getPrivate(); // delete the entry from the CCA key storage area // (An exception is thrown if the CCA key storage area entry does not exist.) // ((ECPrivateHWKey)privKey).deletePKDSEntry(); // // Note that, in this example, the Java key objects still // exist, but the CCA key storage area entry they represent has been deleted. // Any attempt to use the objects "pubKey" or "privKey" will // cause an exception containing a hardware return code and // reason code. //
// create a new CCA key storage area entry and key objects to represent it // AlgorithmParameterSpec spec = new ECHWKeyParameterSpec(256, KeyHWAttributeValues.PKDS, KeyHWAttributeValues.KEYMANAGEMENT, "ANEC.KEYPAIR"); KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "IBMJCECCA"); generator.initialize(spec); KeyPair keyPair = generator.generateKeyPair(); PublicKey pubKey = keyPair.getPublic(); PrivateKey privKey = keyPair.getPrivate(); // delete the entry from the CCA key storage area // (An exception is thrown if the CCA key storage area entry does not exist.) // ((ECPrivateHWKey)privKey).deletePKDSEntry(); // // Note that, in this example, the Java key objects still // exist, but the CCA key storage area entry they represent has been deleted. // Any attempt to use the objects "pubKey" or "privKey" will // cause an exception containing a hardware return code and // reason code. //
Operations
The IBMJCECCA provider supports Diffie-Hellman Key Agreement with elliptic curve keys (Elliptic Curve Diffie-Hellman) by using hardware cryptography, which allows the use of the more secure CCA key storage area stored elliptic curve key pairs. With a CCA key storage area stored elliptic curve key pair, the sensitive private key is never made available in the clear.
Performing Diffie-Hellman Key Agreement by using elliptic curve keys with the IBMJCECCA provider allows the generation of raw secret from the Diffie-Hellman process and allows the key derivation of symmetric hardware keys by using the Static Unified Model key agreement scheme. By default, the resulting derived key object contains a SECURE_INTERNAL_TOKEN key.
If a KDFParameterSpec
object is created with no type or type
KeyType.SECURE_INTERNAL_TOKEN
specified, and the Elliptic Curve Diffie-Hellman Key
Agreement is initialized with this KDFParameterSpec
object, the resulting derived
symmetric key object contains a SECURE_INTERNAL_TOKEN hardware token. This token contains the key
encrypted with the host primary key. If a
KDFParameterSpec
object is created with type KeyType.CKDS
, and the
Elliptic Curve Diffie-Hellman Key Agreement is initialized with this
KDFParameterSpec
object, the resulting derived symmetric key object contains the
label for a CCA key storage area entry that contains a hardware token. This token contains the key
encrypted with the host primary key.
Elliptic Curve Diffie-Hellman supports key derivation of symmetric hardware keys with different key usage attributes. The following key algorithm and usage types are supported:
- CIPHER DES key
- CIPHER, EXPORTER, or IMPORTER double length (112-bit) Triple DES key
- DATA, EXPORTER, or IMPORTER AES key
For a detailed explanation of symmetric key usage types, see the Functions of the Symmetric Cryptographic Keys section in the documentation for your version of z/OS. Note that not all the symmetric key usage types that are available in CCA are supported by the IBMJCECCA provider.
When you initialize Elliptic Curve Diffie-Hellman Key Agreement for key derivation, ensure that a
KDFParameterSpec
object with shared information is constructed and used. A unique
shared information set that accompanies each Elliptic Curve Diffie-Hellman Key Agreement ensures
that the same keying material is not derived more than once. Refer to the NIST SP 800-56A
publication for more information and recommendations about the formatting of this field.
The following example illustrates generating a raw secret from the Diffie-Hellman process:
// Party A generates a shared secret by using his or her own private
// EC key and the public EC key of party B
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
partyAKeyAgreement.init(partyAPrivateKey, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
byte[] partyASharedSecret = partyAKeyAgreement.generateSecret();
// Party B generates a shared secret by using his or her own private
// EC key and the public EC key of party A
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
partyBKeyAgreement.init(partyBPrivateKey, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
byte[] partyBSharedSecret = partyBKeyAgreement.generateSecret();
// The shared secret generated through this key agreement process
// by both party A and party B should have the same byte array contents
The following example illustrates key derivation of DES CIPHER hardware keys by using the static unified model of the Key Agreement scheme:
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyType;
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyUsage;
// Party A
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
// Party A wants to derive a 56-bit hardware CIPHER key enciphered
// under the local primary key, the sharedInfo byte array is uniquely
// constructed for this key derivation and shared with party B
//
KDFParameterSpec partyASpec = new KDFParameterSpec(
56, sharedInfo, KeyType.SECURE_INTERNAL_TOKEN, null, KeyUsage.OP_CIPHER);
// Party A derives a hardware DES key by using his or her own private
// EC key and the public EC key of party B
//
partyAKeyAgreement.init(partyAPrivateKey, partyASpec, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
SecretKey partyASecretKey = partyAKeyAgreement.generateSecret("DES");
// Party B
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
// Party B uses the exact same key derivation specification as party A
// Party B must also use the exact same sharedInfo byte array as party A
//
KDFParameterSpec partyBSpec = new KDFParameterSpec(
56, sharedInfo, KeyType.SECURE_INTERNAL_TOKEN, null, KeyUsage.OP_CIPHER);
// Party B derives a hardware DES key by using his or her own private
// EC key and the public EC key of party A
//
partyBKeyAgreement.init(partyBPrivateKey, partyBSpec, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
SecretKey partyBSecretKey = partyBKeyAgreement.generateSecret("DES");
// The same hardware DES key is generated through this key derivation
// process by both party A and party B
The following example illustrates key derivation of a double length (112-bit) Triple DES EXPORTER key and a double length (112-bit) Triple DES IMPORTER key by using the static unified model of Key Agreement scheme. Both keys are stored in the CCA key storage area:
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyType;
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyUsage;
// Party A
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
// Party A wants to derive an 112-bit hardware EXPORTER key enciphered
// under the local primary key and stored in the CCA key storage area, the sharedInfo
// byte array is uniquely constructed for this key derivation and shared
// with party B
//
KDFParameterSpec partyASpec = new KDFParameterSpec(
112, sharedInfo, KeyType.CKDS, null, KeyUsage.OP_EXPORTER);
// Party A derives a double length Triple DES EXPORTER key by using
// his or her own private EC key and the public EC key of party B
//
partyAKeyAgreement.init(partyAPrivateKey, partyASpec, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
SecretKey partyAExporterKey = partyAKeyAgreement.generateSecret("DESede");
// Party B
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
// Party B uses mostly the same key derivation specification as
// party A, with the exception that he or she is deriving an IMPORTER
// key instead of an EXPORTER key. With an IMPORTER key, party B is
// able to import keys that are exported with party A's EXPORTER key
// Party B must use the exact same sharedInfo byte array as party A
//
KDFParameterSpec partyBSpec = new KDFParameterSpec(
112, sharedInfo, KeyType.CKDS, null, KeyUsage.OP_IMPORTER);
// Party B derives a double length Triple DES IMPORTER key by using
// his or her own private EC key and the public EC key of party A.
//
partyBKeyAgreement.init(partyBPrivateKey, partyBSpec, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
SecretKey partyBImporterKey = partyBKeyAgreement.generateSecret("DESede");
// The hardware Triple DES keys generated through this key derivation
// process by party A and party B are an EXPORTER/IMPORTER key pair
// Keys exported or wrapped by party A's EXPORTER key may be imported
// or unwrapped by party B's IMPORTER key
The following example illustrates key derivation of a double length (112-bit) Triple DES EXPORTER key and a double length (112-bit) Triple DES IMPORTER key by using the static unified model of Key Agreement scheme. In this example, the EXPORTER key and the IMPORTER key are created with the NoCvKEK option enabled. Both keys are stored in the CCA key storage area:
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyType;
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyUsage;
// Party A
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
// Party A wants to derive an 112-bit hardware EXPORTER key enciphered
// under the local primary key and stored in the CCA key storage area, the sharedInfo
// byte array is uniquely constructed for this key derivation and shared
// with party B.
// The last parameter specifies that the NoCvKEK option should be
// enabled.
//
KDFParameterSpec partyASpec = new KDFParameterSpec(
112, sharedInfo, KeyType.CKDS, null, KeyUsage.OP_EXPORTER, true);
// Party A derives a double length Triple DES EXPORTER key by using
// his or her own private EC key and the public EC key of party B
//
partyAKeyAgreement.init(partyAPrivateKey, partyASpec, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
SecretKey partyAExporterKey = partyAKeyAgreement.generateSecret("DESede");
// Party B
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
// Party B uses mostly the same key derivation specification as
// party A, with the exception that he or she is deriving an IMPORTER
// key instead of an EXPORTER key. With an IMPORTER key, party B is
// able to import keys that are exported with party A's EXPORTER key
// Party B must use the exact same sharedInfo byte array as party A
// The last parameter specifies that the NoCvKEK option should be
// enabled.
//
KDFParameterSpec partyBSpec = new KDFParameterSpec(
112, sharedInfo, KeyType.CKDS, null, KeyUsage.OP_IMPORTER, true);
// Party B derives a double length Triple DES IMPORTER key by using
// his or her own private EC key and the public EC key of party A
//
partyBKeyAgreement.init(partyBPrivateKey, partyBSpec, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
SecretKey partyBImporterKey = partyBKeyAgreement.generateSecret("DESede");
// The hardware Triple DES keys generated through this key derivation
// process by party A and party B are an EXPORTER/IMPORTER key pair
// Keys exported or wrapped by party A's EXPORTER key may be imported
// or unwrapped by party B's IMPORTER key. Because the keys have the
// NoCvKEK option enabled, they are suitable for exchanging keys with
// non-z systems.
For information about EXPORTER and IMPORTER keys, see Symmetric transport keys (key encrypting keys).
The following example illustrates key derivation of a 256-bit AES DATA hardware key by using the static unified model of Key Agreement scheme:
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyType;
import com.ibm.crypto.hdwrCCA.provider.SymmetricKeyConstants.KeyUsage;
// Party A
//
KeyAgreement partyAKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
// Party A wants to derive a 256-bit hardware DATA key enciphered
// under the local primary key, the sharedInfo byte array is uniquely
// constructed for this key derivation and shared with party B
//
KDFParameterSpec partyASpec = new KDFParameterSpec(
256, sharedInfo, KeyType.SECURE_INTERNAL_TOKEN, null, KeyUsage.OP_DATA);
// Party A derives a 256-bit hardware AES key by using his or her own
// private EC key and the public EC key of party B
//
partyAKeyAgreement.init(partyAPrivateKey, partyASpec, (SecureRandom) null);
partyAKeyAgreement.doPhase(partyBPublicKey, true);
SecretKey partyASecretKey = partyAKeyAgreement.generateSecret("AES");
// Party B
//
KeyAgreement partyBKeyAgreement = KeyAgreement.getInstance("ECDH", "IBMJCECCA");
// Party B uses the exact same key derivation specification as party A
// Party B must use the exact same sharedInfo byte array as party A
//
KDFParameterSpec partyBSpec = new KDFParameterSpec(
256, sharedInfo, KeyType.SECURE_INTERNAL_TOKEN, null, KeyUsage.OP_DATA);
// Party B derives a 256-bit hardware AES key by using his or her own
// private EC key and the public EC key of party A
//
partyBKeyAgreement.init(partyBPrivateKey, partyBSpec, (SecureRandom) null);
partyBKeyAgreement.doPhase(partyAPublicKey, true);
SecretKey partyBSecretKey = partyBKeyAgreement.generateSecret("AES");
// The same hardware AES key is generated through this key derivation
// process by both party A and party B