FileDocCategorySizeDatePackage
CipherSpi.javaAPI DocAndroid 1.5 API23926Wed May 06 22:41:02 BST 2009javax.crypto

CipherSpi

public abstract class CipherSpi extends Object
This class defines the Service Provider Interface (SPI) for cryptographic ciphers.

Implementers of cryptographic ciphers must implement all the abstract methods for every cipher they implement. {@code CipherSpi} instances are created along with ciphers when the {@link Cipher#getInstance} method is called. A {@code Cipher} is referenced by a transformation, which is a string that describes the operation (or set of operations), always consisting of the cipher's name and optionally followed by a mode and a padding, in the form:

  • "algorithm"
  • or
  • "algorithm/mode/padding"
The following behavior should be implemented for obtaining {@code Cipher} instances.

When one of the {@link Cipher#getInstance} factory methods is called with a transformation that is only an algorithm, check if the provider defines a {@code CipherSpi} for "algorithm", if so: return it, otherwise throw a {@link NoSuchAlgorithmException}.

The following rules apply when a transformation is of the form "algorithm/mode/padding":

    1. The Provider has a {@code CipherSpi} subclass registered for "algorithm/mode/padding": return it, otherwise go to step 2.
    2. The Provider has a {@code CipherSpi} subclass registered for "algorithm/mode": instantiate it, call {@link CipherSpi#engineSetPadding(String) engineSetPadding(String)} for the padding name and return it, otherwise go to step 3.
    3. The Provider has a {@code CipherSpi} subclass registered for "algorithm//padding": instantiate it, call {@link CipherSpi#engineSetMode(String) engineSetMode(String)} for the mode name and return it, otherwise go to step 4.
    4. The Provider has a {@code CipherSpi} subclass registered for "algorithm": instantiate it, call {@link CipherSpi#engineSetMode(String) engineSetMode(String)} for the mode name , call {@link CipherSpi#engineSetPadding(String) engineSetPadding(String)} for the padding name and return it, otherwise throw a {@link NoSuchAlgorithmException}.

see
Cipher
since
Android 1.0

Fields Summary
Constructors Summary
public CipherSpi()
Creates a new {@code CipherSpi} instance.

since
Android 1.0

    
Methods Summary
protected abstract byte[]engineDoFinal(byte[] input, int inputOffset, int inputLen)
Finishes a multi-part transformation (encryption or decryption).

Processes the {@code inputLen} bytes in {@code input} buffer at {@code inputOffset}, and any bytes that have been buffered in previous {@code update} calls.

param
input the input buffer.
param
inputOffset the offset in the input buffer.
param
inputLen the length of the input.
return
the final bytes from the transformation.
throws
IllegalBlockSizeException if the size of the resulting bytes is not a multiple of the cipher block size.
throws
BadPaddingException if the padding of the data does not match the padding scheme.
since
Android 1.0

protected abstract intengineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
Finishes a multi-part transformation (encryption or decryption).

Processes the {@code inputLen} bytes in {@code input} buffer at {@code inputOffset}, and any bytes that have been buffered in previous {@code update} calls.

param
input the input buffer.
param
inputOffset the offset in the input buffer.
param
inputLen the length of the input.
param
output the output buffer for the transformed bytes.
param
outputOffset the offset in the output buffer.
return
the number of bytes placed in the output buffer.
throws
ShortBufferException if the size of the {@code output} buffer is too small.
throws
IllegalBlockSizeException if the size of the resulting bytes is not a multiple of the cipher block size.
throws
BadPaddingException if the padding of the data does not match the padding scheme.
since
Android 1.0

protected intengineDoFinal(java.nio.ByteBuffer input, java.nio.ByteBuffer output)
Finishes a multi-part transformation (encryption or decryption).

Processes the {@code input.remaining()} bytes in {@code input} buffer at {@code input.position()}, and any bytes that have been buffered in previous {@code update} calls. The transformed bytes are placed into {@code output} buffer.

param
input the input buffer.
param
output the output buffer.
return
the number of bytes placed into the output buffer.
throws
ShortBufferException if the size of the {@code output} buffer is too small.
throws
IllegalBlockSizeException if the size of the resulting bytes is not a multiple of the cipher block size.
throws
BadPaddingException if the padding of the data does not match the padding scheme.
throws
IllegalArgumentException if the input buffer and the output buffer are the same object.
throws
IllegalStateException if this cipher instance is not initialized for encryption or decryption.

        if (input == null) {
            throw new NullPointerException(Messages.getString("crypto.0C")); //$NON-NLS-1$
        }
        if (output == null) {
            throw new NullPointerException(Messages.getString("crypto.0D")); //$NON-NLS-1$
        }
        int position = input.position();
        int limit = input.limit();

        if ((limit - position) <= 0) {
            return 0;
        }
        byte[] bInput;
        byte[] bOutput;

        if (input.hasArray()) {
            bInput = input.array();
            int offset = input.arrayOffset();
            bOutput = engineDoFinal(bInput, offset + position, limit - position);
            input.position(limit);
        } else {
            bInput = new byte[limit - position];
            input.get(bInput);
            bOutput = engineDoFinal(bInput, 0, limit - position);
        }
        if (output.remaining() < bOutput.length) {
            throw new ShortBufferException(Messages.getString("crypto.0E")); //$NON-NLS-1$
        }
        try {
            output.put(bOutput);
        } catch (java.nio.BufferOverflowException e) {
            throw new ShortBufferException(Messages.getString("crypto.0F", e)); //$NON-NLS-1$
        }
        return bOutput.length;
    
protected abstract intengineGetBlockSize()
Returns the block size of this cipher (in bytes)

return
the block size of this cipher, or zero if this cipher is not a block cipher.
since
Android 1.0

protected abstract byte[]engineGetIV()
Returns the Initialization Vector (IV) that was used to initialize this cipher or {@code null} if none was used.

return
the Initialization Vector (IV), or {@code null} if none was used.
since
Android 1.0

protected intengineGetKeySize(java.security.Key key)
Returns the size of a specified key object in bits. This method has been added to this class (for backwards compatibility, it cannot be abstract). If this method is not overridden, it throws an {@code UnsupportedOperationException}.

param
key the key to get the size for.
return
the size of a specified key object in bits.
throws
InvalidKeyException if the size of the key cannot be determined by this implementation.
since
Android 1.0

        throw new UnsupportedOperationException(
                Messages.getString("crypto.12")); //$NON-NLS-1$
    
protected abstract intengineGetOutputSize(int inputLen)
Returns the size for a buffer (in bytes), that the next call to {@code update} of {@code doFinal} would return, taking into account any buffered data from previous {@code update} calls and padding.

The actual output length of the next call to {@code update} or {@code doFinal} may be smaller than the length returned by this method.

param
inputLen the length of the input (in bytes).
return
the size for a buffer (in bytes).
since
Android 1.0

protected abstract java.security.AlgorithmParametersengineGetParameters()
Returns the parameters that where used to create this cipher instance.

These may be a the same parameters that were used to create this cipher instance, or may be a combination of default and random parameters, depending on the underlying cipher implementation.

return
the parameters that where used to create this cipher instance, or {@code null} if this cipher instance does not have any parameters at all.
since
Android 1.0

protected abstract voidengineInit(int opmode, java.security.Key key, java.security.AlgorithmParameters params, java.security.SecureRandom random)
Initializes this cipher instance with the specified key, algorithm parameters and a source of randomness.

The cipher will be initialized for the specified operation (one of: encryption, decryption, key wrapping or key unwrapping) depending on {@code opmode}.

If this cipher instance needs any algorithm parameters and {@code params} is {@code null}, the underlying implementation of this cipher is supposed to generate the required parameters (using its provider or random values). Random values are generated using {@code random}.

When a cipher instance is initialized by a call to any of the {@code init} methods, the state of the instance is overridden, means it is equivalent to creating a new instance and calling it {@code init} method.

param
opmode the operation this cipher instance should be initialized for (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code WRAP_MODE} or {@code UNWRAP_MODE}).
param
key the input key for the operation.
param
params the algorithm parameters.
param
random the source of randomness to use.
throws
InvalidKeyException if the specified key cannot be used to initialize this cipher instance.
throws
InvalidAlgorithmParameterException if the specified parameters are inappropriate for this cipher.
since
Android 1.0

protected abstract voidengineInit(int opmode, java.security.Key key, java.security.SecureRandom random)
Initializes this cipher instance with the specified key and a source of randomness.

The cipher will be initialized for the specified operation (one of: encryption, decryption, key wrapping or key unwrapping) depending on {@code opmode}.

If this cipher instance needs any algorithm parameters or random values that the specified key cannot provide, the underlying implementation of this cipher is supposed to generate the required parameters (using its provider or random values). Random values will be generated using {@code random};

When a cipher instance is initialized by a call to any of the {@code init} methods, the state of the instance is overridden, means it is equivalent to creating a new instance and calling it {@code init} method.

param
opmode the operation this cipher instance should be initialized for (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code WRAP_MODE} or {@code UNWRAP_MODE}).
param
key the input key for the operation.
param
random the source of randomness to use.
throws
InvalidKeyException if the specified key cannot be used to initialize this cipher instance.
since
Android 1.0

protected abstract voidengineInit(int opmode, java.security.Key key, java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random)
Initializes this cipher instance with the specified key, algorithm parameters and a source of randomness.

The cipher will be initialized for the specified operation (one of: encryption, decryption, key wrapping or key unwrapping) depending on {@code opmode}.

If this cipher instance needs any algorithm parameters and {@code params} is {@code null}, the underlying implementation of this cipher is supposed to generate the required parameters (using its provider or random values). Random values are generated using {@code random}.

When a cipher instance is initialized by a call to any of the {@code init} methods, the state of the instance is overridden, means it is equivalent to creating a new instance and calling it {@code init} method.

param
opmode the operation this cipher instance should be initialized for (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code WRAP_MODE} or {@code UNWRAP_MODE}).
param
key the input key for the operation.
param
params the algorithm parameters.
param
random the source of randomness to use.
throws
InvalidKeyException if the specified key cannot be used to initialize this cipher instance.
throws
InvalidAlgorithmParameterException it the specified parameters are inappropriate for this cipher.
since
Android 1.0

protected abstract voidengineSetMode(java.lang.String mode)
Sets the mode for this cipher.

param
mode the name of the cipher mode.
throws
NoSuchAlgorithmException if the specified cipher mode is not supported by this provider.
since
Android 1.0

protected abstract voidengineSetPadding(java.lang.String padding)
Sets the padding method for this cipher.

param
padding the name of the padding method.
throws
NoSuchPaddingException if the specified padding method is not supported by this cipher.
since
Android 1.0

protected java.security.KeyengineUnwrap(byte[] wrappedKey, java.lang.String wrappedKeyAlgorithm, int wrappedKeyType)
Unwraps a key using this cipher instance.

This method has been added to this class (for backwards compatibility, it cannot be abstract). If this method is not overridden, it throws an {@code UnsupportedOperationException}.

param
wrappedKey the wrapped key to unwrap.
param
wrappedKeyAlgorithm the algorithm for the wrapped key.
param
wrappedKeyType the type of the wrapped key (one of: {@code SECRET_KEY}, {@code PRIVATE_KEY} or {@code PUBLIC_KEY})
return
the unwrapped key.
throws
InvalidKeyException if the {@code wrappedKey} cannot be unwrapped to a key of type {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}.
throws
NoSuchAlgorithmException if no provider can be found that can create a key of type {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}.
since
Android 1.0

        throw new UnsupportedOperationException(
                Messages.getString("crypto.11")); //$NON-NLS-1$
    
protected abstract byte[]engineUpdate(byte[] input, int inputOffset, int inputLen)
Continues a multi-part transformation (encryption or decryption). The transformed bytes are returned.

param
input the input bytes to transform.
param
inputOffset the offset in the input to start.
param
inputLen the length of the input to transform.
return
the transformed bytes in a new buffer, or {@code null} if the input has zero length.
throws
IllegalStateException if this cipher instance is not initialized for encryption or decryption.
throws
IllegalArgumentException if the input is null, or if {@code inputOffset} and {@code inputLen} do not specify a valid chunk in the input buffer.
since
Android 1.0

protected abstract intengineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
Continues a multi-part transformation (encryption or decryption). The transformed bytes are stored in the {@code output} buffer.

If the size of the {@code output} buffer is too small to hold the result, a {@code ShortBufferException} is thrown. Use {@link Cipher#getOutputSize getOutputSize} to check for the size of the output buffer.

param
input the input bytes to transform.
param
inputOffset the offset in the input to start.
param
inputLen the length of the input to transform.
param
output the output buffer.
param
outputOffset the offset in the output buffer.
return
the number of bytes placed in output.
throws
ShortBufferException if the size of the {@code output} buffer is too small.
since
Android 1.0

protected intengineUpdate(java.nio.ByteBuffer input, java.nio.ByteBuffer output)
Continues a multi-part transformation (encryption or decryption). The {@code input.remaining()} bytes starting at {@code input.position()} are transformed and stored in the {@code output} buffer.

If the {@code output.remaining()} is too small to hold the transformed bytes a {@code ShortBufferException} is thrown. Use {@link Cipher#getOutputSize getOutputSize} to check for the size of the output buffer.

param
input the input buffer to transform.
param
output the output buffer to store the result within.
return
the number of bytes stored in the output buffer.
throws
ShortBufferException if the size of the {@code output} buffer is too small.
since
Android 1.0

        if (input == null) {
            throw new NullPointerException(Messages.getString("crypto.0C")); //$NON-NLS-1$
        }
        if (output == null) {
            throw new NullPointerException(Messages.getString("crypto.0D")); //$NON-NLS-1$
        }
        int position = input.position();
        int limit = input.limit();
        if ((limit - position) <= 0) {
            return 0;
        }
        byte[] bInput;
        byte[] bOutput;
        if (input.hasArray()) {
            bInput = input.array();
            int offset = input.arrayOffset();
            bOutput = engineUpdate(bInput, offset + position, limit - position);
            input.position(limit);
        } else {
            bInput = new byte[limit - position];
            input.get(bInput);
            bOutput = engineUpdate(bInput, 0, limit - position);
        }
        if (output.remaining() < bOutput.length) {
            throw new ShortBufferException(Messages.getString("crypto.0E")); //$NON-NLS-1$
        }
        try {
            output.put(bOutput);
        } catch (java.nio.BufferOverflowException e) {
            throw new ShortBufferException(Messages.getString("crypto.0F", e)); //$NON-NLS-1$
        }
        return bOutput.length;
    
protected byte[]engineWrap(java.security.Key key)
Wraps a key using this cipher instance. This method has been added to this class (for backwards compatibility, it cannot be abstract). If this method is not overridden, it throws an {@code UnsupportedOperationException}.

param
key the key to wrap.
return
the wrapped key
throws
IllegalBlockSizeException if the size of the resulting bytes is not a multiple of the cipher block size.
throws
InvalidKeyException if this cipher instance cannot wrap this key.
since
Android 1.0

        throw new UnsupportedOperationException(
                Messages.getString("crypto.10")); //$NON-NLS-1$