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
// 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();
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();
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();
// 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();
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();
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
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();
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();