Managing Algorithm Parameters

The parameters being used by the underlying Cipher implementation, which were either explicitly passed to the init method by the application or generated by the underlying implementation itself, can be retrieved from the Cipher object by calling its getParameters method, which returns the parameters as a java.security.AlgorithmParameters object (or null if no parameters are being used). If the parameter is an initialization vector (IV), it can also be retrieved by calling the getIV method.

In the following example, a Cipher object implementing password-based encryption is initialized with just a key and no parameters. However, the selected algorithm for password-based encryption requires two parameters - a salt and an iteration count. Those parameters will be generated by the underlying algorithm implementation itself. The application can retrieve the generated parameters from the Cipher object as follows:

 import javax.crypto.*;
 import java.security.AlgorithmParameters;

 // get cipher object for password-based encryption
 Cipher c = Cipher.getInstance("PBEWithMD5AndDES");

 // initialize cipher for encryption, without supplying
 // any parameters. Here, "myKey" is assumed to refer 
 // to an already-generated key.
 c.init(Cipher.ENCRYPT_MODE, myKey);

 // encrypt some data and store away ciphertext
 // for later decryption
 byte[] cipherText = c.doFinal("This is just an example".getBytes());

 // retrieve parameters generated by underlying cipher
 // implementation
 AlgorithmParameters algParams = c.getParameters();

 // get parameter encoding and store it away
 byte[] encodedAlgParams = algParams.getEncoded();

The same parameters that were used for encryption must be used for decryption. They can be instantiated from their encoding and used to initialize the corresponding Cipher object for decryption, as follows:

 import javax.crypto.*;
 import java.security.AlgorithmParameters;

 // get parameter object for password-based encryption
 AlgorithmParameters algParams;
 algParams = 
 AlgorithmParameters.getInstance("PBEWithMD5AndDES");

 // initialize with parameter encoding from previous
 algParams.init(encodedAlgParams);

 // get cipher object for password-based encryption
 Cipher c = Cipher.getInstance("PBEWithMD5AndDES");

 // initialize cipher for decryption, using one of the 
 // init() methods that takes an AlgorithmParameters 
 // object, and pass it the algParams object from previous
 c.init(Cipher.DECRYPT_MODE, myKey, algParams);

If you did not specify any parameters when you initialized a Cipher object, and you are not sure whether the underlying implementation uses any parameters, you can find out by simply calling the getParameters method of your Cipher object and checking the value returned. A return value of null indicates that no parameters were used.

The following cipher algorithms implemented by the IBMJCE provider use parameters:

  • DES, DES-EDE, and Blowfish, when used in feedback (such as CBC, CFB, CTR, OFB, or PCBC) mode, use an initialization vector (IV). The javax.crypto.spec.IvParameterSpec class can be used to initialize a Cipher object with a given IV.
  • PBEWithMD5AndDES uses a set of parameters, comprising a salt and an iteration count. The javax.crypto.spec.PBEParameterSpec class can be used to initialize a Cipher object implementing PBEWithMD5AndDES with a given salt and iteration count.

Note that you do not have to worry about storing or transferring any algorithm parameters for use by the decryption operation if you use the SealedObject class. This class attaches the parameters used for sealing (encryption) to the encrypted object contents, and uses the same parameters for unsealing (decryption).