Key Generation
ProtectToolkit-J can generate random keys for each of the cipher algorithms it supports. These keys are Cryptoki session keys; they are not stored permanently on the adapter. Session keys are not thread-safe and so may only be used by a single Cipher instance and a single Signature (or MAC) instance at any time. Thus, it is allowable to use a DES key for encryption in a Cipher instance and a single MAC instance but not two Cipher instances. Keys fetched from the ProtectToolkit-J KeyStore do not have this restriction.
When generating a random key, the size of the key will be as follows:
Key Name | Default Key Size | Valid Key Sizes |
---|---|---|
DES | 56 | 56 |
DESede | 196 | 128,196 |
AES | 128 | 128,196, 256 |
IDEA | 128 | 128 |
CAST128 | 128 | 8-128 |
RC2 | 64 | 0-1024 |
RC4 | 64 | 8-2048 |
RSA | 1024 | 512-4096 |
DSA | 1024 | 512-3072 |
DH | 1024 | 512-4096 |
This section describes the following:
Secret Keys
The secret key Ciphers will simply generate the appropriate number of random bytes for the key (there are no checks for weak keys).
The following example will generate a random double-length DESede key. Generation of a key for a different algorithm is as simple as changing the algorithm name and choosing an appropriate key length.
KeyGenerator keyGen = KeyGenerator.getInstance(“DESede”, “SAFENET”);
keyGen.init(128);
SecretKey key = keyGen.generateKey();
Public Keys
RSA Keys
The RSA key pair generator will generate keys based on an algorithm determined by key size. If the size is some multiple of 256 bits greater than 1024, the algorithm specified in ANSI X 9.31 will be used. Otherwise, the one specified in PKCS#1 is used. The key pair will be compatible with PKCS#1 RSA, ISO/IEC 9796 RSA and X.509 (raw) RSA standards. ANSI X 9.31 keys have a random 16-bit exponent, while PKCS#1 public exponent is fixed to the Fermat-4 value (hex 0x1001).
The following example will generate a 2048-bit RSA key pair.
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(“RSA”,
“SAFENET”);
keyPairGen.initialise(2048);
KeyPair keyPair = keyPairGen.generateKeyPair();
DSA Keys
The DSA key pair generator will generate keys based on the algorithm specified in the Digital Signature Standard (FIPS PUB 186-1). DSA key generation requires a number of parameters; these are generally fixed in a given application, but they are also usually randomly generated for a particular application. At present, ProtectToolkit-J does not include any mechanism to generate these parameters. However, the DSA key pair generator can accept these parameters (via a java.security.spec.DSAParameterSpec) or has configured defaults for 512- or 1024-bit keys (these defaults are listed in the JCE specification).
The following example will generate a 1024-bit DSA key pair, using the default DSA parameters.
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(“DSA”,
“SAFENET”);
keyPairGen.initialise(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
This example will use the provided DSA parameters, rather than the built-in defaults.
BigInteger p, q, g; // These are the parameter values
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(“DSA”,
“SAFENET”);
DSAParameterSpec keyParamSpec = new DSAParamterSpec(p, q, g);
keyPairGen.initialise(keyParamSpec);
KeyPair keyPair = keyPairGen.generateKeyPair();
Diffie-Hellman Keys
The DH KeyPairGenerator will generate Diffie-Hellman keys suitable for the Diffie-Hellman key agreement protocol. Diffie-Hellman key generation requires a number of parameters; these are generally fixed in a given application, but they are also usually randomly generated for a particular application. At present, ProtectToolkit-J does not include any mechanism to generate these parameters. However, the DH key pair generator can accept these parameters (via a java.security.spec.DHParameterSpec) or has configured defaults for 512- or 1024-bit keys (these defaults are listed in the JCE specification).
The following example will generate a 1024-bit DH key pair, using the default DH parameters.
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(“DH”,
“SAFENET”);
keyPairGen.initialise(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
This example will use the provided DH parameters, rather than the built-in defaults.
BigInteger p, g; // These are the parameter values
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(“DH”,
“SAFENET”);
DSAParameterSpec keyParamSpec = new DHParamterSpec(p, g);
keyPairGen.initialise(keyParamSpec);
KeyPair keyPair = keyPairGen.generateKeyPair();
KeyAgreement Protocols
ProtectToolkit-J also includes mechanisms which allow for the creation of keys based on other keys.
Diffie-Hellman KeyAgreement
The DH KeyAgreement algorithm can be used to perform a 2-phase key Diffie-Hellman key agreement.
Xor Key Derive
This algorithm may be used to derive a new key from an existing key and a known data pattern. The key value and the data pattern will be combined on the adapter using the XOR function. For example if the initial key has the value 0x12,0x34 and the data pattern has the value 0x89,0xAB, the resultant key will have the value 0x88,0x88.
The actual key values will be combined within the adapter to ensure their values are never compromised. Also, the newly-created key will inherit the attributes of the two keys such that the derived key will be as protected as the two original keys. This mechanism may not be used to change the key type of the base key. Therefore, if the base key is a DES key, the derived key must also be a DES key.
This mechanism can only be used on keys with the CKA_DERIVE attribute set to true
. This will the case for keys generated with any of the ProtectToolkit-J mechanisms (such as KeyGenerator classes). However, if the key is generated with the Browser application, be sure to check the ‘Derive’ checkbox.
Do not create an instance of this class directly, rather use the KeyAgreement.getInstance() factory method:
KeyAgreement ka = KeyAgreement.getInstance("XorBaseAndKey", "SAFENET");
Once created, the instance should be initialized using the base key. Then, to combine with the data pattern, call the doPhase() method with a SecretKeySpec instance created with the data pattern and true for the lastPhase parameter.
Finally to obtain the newly created instance call the generateSecret() method with the appropriate key name.
For example:
byte[] data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
ka.init(baseKey);
ka.doPhase(new SecretKeySpec(data), true);
Key newKey = ka.generateSecret("DES");
NOTE The key material generated must be compatible with the key type requested in the generateSecret() method call. Specifically, the length of the new key will be the minimum of the lengths of the two components.