Symmetric transport keys (key encrypting keys)

The IBM Common Cryptographic Architecture (CCA) has a feature called key separation, where it controls the use of keys by separating them into unique usage types, allowing the use of a specific type of key only for its intended purpose. For example, a key that is used to protect data cannot be used to protect a key.

The IBMJCECCA provider supports symmetric key generation of DATA encrypting keys by default. This key usage type is the most commonly used among symmetric keys, and is used to protect data privacy. In addition to DATA encrypting keys, the IBMJCECCA provider is also capable of generating transport keys, also known as key encrypting keys. Transport keys are used to protect keys during distribution from one system to another. The following types of transport keys are supported by the IBMJCECCA provider:

  • Double length 112-bit EXPORTER Triple DES key
  • Double length 112-bit IMPORTER Triple DES key
  • All lengths of EXPORTER AES key
  • All lengths of IMPORTER AES key

Transport keys can be generated through a key generator or derived through a Diffie-Hellman key agreement. In both cases, the key generator or key agreement must be initialized with an AlgorithmParameterSpec object that contains cryptographic parameters that are relevant for transport key generation or key derivation.

On z/OS®, CKDS type AES transport keys require a CKDS that supports variable length records. Refer to the section titled Converting a CKDS from fixed length to variable length record format in the ICSF System Programmer's Guide for more information or contact your system administrator.

In general, keys that are protected with transport keys that are generated through the IBMJCECCA provider can be distributed only among IBM Z® systems. Because of the additional security that is provided by the use of control vectors on an IBM Z system, it is unlikely that a key that is protected with a transport key on an IBM Z system can be correctly reconstructed on a system that isn't IBM Z, even when the correct IMPORTER key is used.

A Triple DES transport key with the NoCvKEK option can be used to exchange keys with non-z systems. A Triple DES transport key with the NoCvKEK option can also be used to exchange keys with z systems, but the security of the key exchange is weakened because a transport key with the NoCvKEK option will not use control vectors. The NoCvKEK option can be specified for a Triple DES transport key when the key is created or when the key is imported. Only Triple DES transport keys in the CCA key storage area can have the NoCvKEK option.

The IBMJCECCA key generator generates transport keys in OPEX form consisting of either an EXPORTER/IMPORTER pair or an IMPORTER/EXPORTER pair. OPEX refers to a pair of keys where the first key is in an operational (OP) form and usable by the local system, and the second key is in an exportable (EX) form that needs to be imported before being usable on a system. Operational (OP) keys are enciphered directly by the local primary key and are represented in Java™ as Key objects. Exportable (EX) keys, on the other hand, are similar to wrapped keys in Java. Exportable (EX) keys are enciphered by an existing operational (OP) EXPORTER key and are represented in Java as an array of bytes.

For a detailed explanation of key usage types and key forms that are supported by the IBM Common Cryptographic Architecture (CCA), refer to the section titled Functions of the Symmetric Cryptographic Keys in the Cryptographic Services Integrated Cryptographic Service Facility Application Programmer's Guide. Note that not all key usage types and key forms that are available in CCA are supported by the IBMJCECCA provider. Furthermore, the IBMJCECCA provider supports only a portion of the transport key functions that are available in the CCA.

Generating transport keys with the IBMJCECCA key generator requires an existing transport key. As a result, systems that do not have transport keys cannot use the key generator to generate transport keys. A solution for such systems is to use IBMJCECCA's Diffie-Hellman key agreement functions to derive their initial transport keys.

In a two party Diffie-Hellman key agreement scheme that uses Elliptic Curve keys, which is the only type of Diffie-Hellman key agreement that is currently supported by the IBMJCECCA provider, one system derives an operational (OP) EXPORTER key while the other system derives the matching operational (OP) IMPORTER key. Keys that are derived through the key agreement are all operational keys, so existing transport keys are not required in this case. For more information about Diffie-Hellman key agreement by using Elliptic Curve keys, see EC operations.

When you generate Triple DES or AES transport keys by using an instance of the IBMJCECCA KeyGenerator class, the com.ibm.crypto.hdwrCCA.provider.DESedeKey or com.ibm.crypto.hdwrCCA.provider.AESKey object that is returned by the key generator represents the operational (OP) key in the OPEX key pairing. This operational key, like any other Java key, can be used directly on the system.

The matching exportable (EX) key generated by the key generator, however, is not a Java key object and cannot be used directly on the system. Similar to other keys that are wrapped by using a cryptographic cipher, it is in an external key token format for export to another system and is represented in Java as an array of bytes. On return from the key generator, this matching exportable (EX) key token can be retrieved by calling the getPairedExternalToken() public method on the returned operational (OP) key. The key token can then be imported or unwrapped on another system to create an equivalent operational Java key object.

Although the IBMJCECCA key generator stores the generated exportable (EX) key token in the returned Java key object that represents the operational (OP) key, the exportable (EX) key is not considered part of the operational (OP) key. As a result, the key token value that represents the exportable (EX) key that is stored in the returned operational (OP) Java key object does not persist when the operational (OP) key is reconstructed, whether through a SecretKeyFactory instance using the key specification of the operational (OP) key or through wrapping and unwrapping of the operational key (OP) with a cryptographic cipher. Calling the getPairedExternalToken() method on the reconstructed operational (OP) key returns null. You should retrieve the external key token of the exportable (EX) key immediately after it is generated by the key generator.

Generating symmetric transport keys

The following sample illustrates generating a 168-bit Triple DES DATA key that contains a hardware key token:
// use CCAAlgorithmParameterSpec to specify key size of 168
//
CCAAlgorithmParameterSpec ccaAlgParmSpec = new CCAAlgorithmParameterSpec(168);

// request that an operational DATA key is to be generated
//
ccaAlgParmSpec.setKeyUsage(KeyUsage.OP_DATA);

KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede", "IBMJCECCA");
keyGenerator.init(ccaAlgParmSpec, null);

// this key object represents the generated operational (OP) DATA key
//
SecretKey tdesDataKey = keyGenerator.generateKey();
The following sample illustrates generating a Triple DES hardware EXPORTER/IMPORTER transport key pair where the operational (OP) EXPORTER key contains a hardware key token that is enciphered by the local primary key and the exportable (EX) IMPORTER key is a hardware key token that is enciphered under an existing triple DES EXPORTER key named tdesPrimaryExporter:
// use CCAAlgorithmParameterSpec to specify key size of 112
//
CCAAlgorithmParameterSpec ccaAlgParmSpec = new CCAAlgorithmParameterSpec(112);

// request that a transport key pair is to be generated
// first key is an operational (OP) EXPORTER key
// second key is an exportable (EX) IMPORTER key
//
ccaAlgParmSpec.setKeyUsage(KeyUsage.OPEX_EXPORTER_IMPORTER);

// specify an existing triple DES EXPORTER key to be used for
// enciphering the generated IMPORTER key
//
ccaAlgParmSpec.setKey2KeyEncryptingKey(tdesPrimaryExporter);

KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede", "IBMJCECCA");
keyGenerator.init(ccaAlgParmSpec, null);

// this key object represents the generated operational (OP) EXPORTER key
//
DESedeKey tdesExporterKey = (com.ibm.crypto.hdwrCCA.provider.DESedeKey) keyGenerator.generateKey();

// this is the exportable (EX) IMPORTER hardware key token, which is
// enciphered (wrapped) under an existing triple DES EXPORTER key named tdesPrimaryExporter
//
byte[] tdesImporterToken = tdesExporterKey.getPairedExternalToken();
The following sample illustrates generating a Triple DES hardware IMPORTER/EXPORTER transport key pair where the operational (OP) IMPORTER key is stored in the CCA key storage area and the exportable (EX) EXPORTER key is a hardware key token that is enciphered under an existing triple DES EXPORTER key named tdesPrimaryExporter:
// use CCAAlgorithmParameterSpec to specify key size of 112, in
// addition, specify that the generated operational key is to be stored
// in the CCA key storage area
//
CCAAlgorithmParameterSpec ccaAlgParmSpec = new CCAAlgorithmParameterSpec(
        112, CCAAlgorithmParameterSpec.CKDS);

// request that a transport key pair is to be generated
// first key is an operational (OP) IMPORTER key
// second key is an exportable (EX) EXPORTER key
//
ccaAlgParmSpec.setKeyUsage(KeyUsage.OPEX_IMPORTER_EXPORTER);

// specify an existing triple DES EXPORTER key to be used for
// enciphering the generated EXPORTER key
//
ccaAlgParmSpec.setKey2KeyEncryptingKey(tdesPrimaryExporter);

KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede", "IBMJCECCA");
keyGenerator.init(ccaAlgParmSpec, null);

// this key object represents the generated operational (OP) IMPORTER
// key, and contains a label for the corresponding CCA key storage area entry
//
DESedeKey tdesImporterKey = (com.ibm.crypto.hdwrCCA.provider.DESedeKey) keyGenerator.generateKey();

// this is the exportable (EX) EXPORTER hardware key token, which is
// enciphered under an existing triple DES EXPORTER key named tdesPrimaryExporter
//
byte[] tdesExporterToken = tdesImporterKey.getPairedExternalToken();
The following sample illustrates generating a 192-bit AES DATA key that contains a hardware key token:
// use CCAAlgorithmParameterSpec to specify key size of 192
//
CCAAlgorithmParameterSpec ccaAlgParmSpec = new CCAAlgorithmParameterSpec(192);

// request that an operational DATA key is to be generated
//
ccaAlgParmSpec.setKeyUsage(KeyUsage.OP_DATA);

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", "IBMJCECCA");
keyGenerator.init(ccaAlgParmSpec, null);

// this key object represents the generated operational (OP) DATA key
//
SecretKey aesDataKey = keyGenerator.generateKey();
The following sample illustrates generating a 256-bit AES hardware EXPORTER/IMPORTER transport key pair where the operational (OP) EXPORTER key contains a hardware key token that is enciphered by the local primary key and the exportable (EX) IMPORTER key is a hardware key token that is enciphered under an existing AES EXPORTER key named aesPrimaryExporter:
// use CCAAlgorithmParameterSpec to specify key size of 256
//
CCAAlgorithmParameterSpec ccaAlgParmSpec = new CCAAlgorithmParameterSpec(256);

// request that a transport key pair is to be generated
// first key is an operational (OP) EXPORTER key
// second key is an exportable (EX) IMPORTER key
//
ccaAlgParmSpec.setKeyUsage(KeyUsage.OPEX_EXPORTER_IMPORTER);

// specify an existing AES EXPORTER key to be used for
// enciphering the generated IMPORTER key
//
ccaAlgParmSpec.setKey2KeyEncryptingKey(aesPrimaryExporter);

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", "IBMJCECCA");
keyGenerator.init(ccaAlgParmSpec, null);

// this key object represents the generated operational (OP) EXPORTER key
//
AESKey aesExporterKey = (com.ibm.crypto.hdwrCCA.provider.AESKey) keyGenerator.generateKey();

// this is the exportable (EX) IMPORTER hardware key token, which is
// enciphered (wrapped) under an existing AES EXPORTER key named aesPrimaryExporter
//
byte[] aesImporterToken = aesExporterKey.getPairedExternalToken();
The following sample illustrates generating a 128-bit AES hardware IMPORTER/EXPORTER transport key pair where the operational (OP) IMPORTER key is stored in the CCA key storage area and the exportable (EX) EXPORTER key is a hardware key token that is enciphered under an existing AES EXPORTER key named aesPrimaryExporter:
// use CCAAlgorithmParameterSpec to specify key size of 128, in
// addition, specify that the generated operational key is to be stored
// in the CCA key storage area
//
CCAAlgorithmParameterSpec ccaAlgParmSpec = new CCAAlgorithmParameterSpec(
        128, CCAAlgorithmParameterSpec.CKDS);

// request that a transport key pair is to be generated
// first key is an operational (OP) IMPORTER key
// second key is an exportable (EX) EXPORTER key
//
ccaAlgParmSpec.setKeyUsage(KeyUsage.OPEX_IMPORTER_EXPORTER);

// specify an existing AES EXPORTER key to be used for
// enciphering the generated EXPORTER key
//
ccaAlgParmSpec.setKey2KeyEncryptingKey(aesPrimaryExporter);

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", "IBMJCECCA");
keyGenerator.init(ccaAlgParmSpec, null);

// this key object represents the generated operational (OP) IMPORTER
// key, and contains a label for the corresponding CCA key storage area entry
//
AESKey aesImporterKey = (com.ibm.crypto.hdwrCCA.provider.AESKey) keyGenerator.generateKey();

// this is the exportable (EX) EXPORTER hardware key token, which is
// enciphered under an existing AES EXPORTER key named aesPrimaryExporter
//
byte[] aesExporterToken = aesImporterKey.getPairedExternalToken();

Generating symmetric transport keys with the NoCvKEK option

The following sample illustrates generating a Triple DES hardware EXPORTER/IMPORTER transport key pair where the operational (OP) EXPORTER key has the NoCvKEK option and is stored in the CCA key storage area and the exportable (EX) IMPORTER key is a hardware key token that is enciphered under an existing triple DES EXPORTER key named tdesPrimaryExporter:
// Use CCAAlgorithmParameterSpec to specify key size of 112 and that
// the generated operational key is to be stored in the CCA key storage area.
// Only a Triple DES transport key in the CCA key storage area can have the NoCvKEK
// option enabled.
//
CCAAlgorithmParameterSpec ccaAlgParmSpec = new CCAAlgorithmParameterSpec(
        112, CCAAlgorithmParameterSpec.CKDS);

// request that a transport key pair is to be generated
// first key is an operational (OP) EXPORTER key
// second key is an exportable (EX) IMPORTER key
//
ccaAlgParmSpec.setKeyUsage(KeyUsage.OPEX_EXPORTER_IMPORTER);

// request that the operational (OP) EXPORTER key have
// the NoCvKEK option
//
ccaAlgParmSpec.setNoCvKEK(true);

// specify an existing triple DES EXPORTER key to be used for
// enciphering the generated IMPORTER key
//
ccaAlgParmSpec.setKey2KeyEncryptingKey(tdesPrimaryExporter);

KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede", "IBMJCECCA");
keyGenerator.init(ccaAlgParmSpec, null);

// This key object represents the generated operational (OP) EXPORTER key.
// Because the NoCvKEK option was specified when it was created,
// it is suitable for exchanging keys with non-z systems.
//
DESedeKey tdesExporterKey = (com.ibm.crypto.hdwrCCA.provider.DESedeKey) keyGenerator.generateKey();

// this is the exportable (EX) IMPORTER hardware key token, which is
// enciphered (wrapped) under an existing triple DES EXPORTER key named tdesPrimaryExporter
//
byte[] tdesImporterToken = tdesExporterKey.getPairedExternalToken();
The following sample illustrates generating a Triple DES hardware IMPORTER/EXPORTER transport key pair where the operational (OP) IMPORTER key has the NoCvKEK option and is stored in the CCA key storage area and the exportable (EX) EXPORTER key is a hardware key token that is enciphered under an existing triple DES EXPORTER key named tdesPrimaryExporter:
// Use CCAAlgorithmParameterSpec to specify key size of 112 and that
// the generated operational key is to be stored in the CCA key storage area.
// Only a Triple DES transport key in the CCA key storage area can have the NoCvKEK
// option enabled.
//
CCAAlgorithmParameterSpec ccaAlgParmSpec = new CCAAlgorithmParameterSpec(
        112, CCAAlgorithmParameterSpec.CKDS);

// request that a transport key pair is to be generated
// first key is an operational (OP) IMPORTER key
// second key is an exportable (EX) EXPORTER key
//
ccaAlgParmSpec.setKeyUsage(KeyUsage.OPEX_IMPORTER_EXPORTER);

// request that the operational (OP) IMPORTER key have
// the NoCvKEK option
//
ccaAlgParmSpec.setNoCvKEK(true);

// specify an existing triple DES EXPORTER key to be used for
// enciphering the generated EXPORTER key
//
ccaAlgParmSpec.setKey2KeyEncryptingKey(tdesPrimaryExporter);

KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede", "IBMJCECCA");
keyGenerator.init(ccaAlgParmSpec, null);

// This key object represents the generated operational (OP) IMPORTER
// key, and contains a label for the corresponding CCA key storage area entry.
// Because the NoCvKEK option was specified when it was created,
// it is suitable for exchanging keys with non-z systems.
//
DESedeKey tdesImporterKey = (com.ibm.crypto.hdwrCCA.provider.DESedeKey) keyGenerator.generateKey();

// this is the exportable (EX) EXPORTER hardware key token, which is
// enciphered under an existing triple DES EXPORTER key named tdesPrimaryExporter
//
byte[] tdesExporterToken = tdesImporterKey.getPairedExternalToken();