tribble.crypto
Class StreamCipherSpi

java.lang.Object
  extended byjavax.crypto.CipherSpi
      extended bytribble.crypto.CipherSpi
          extended bytribble.crypto.StreamCipherSpi

public class StreamCipherSpi
extends CipherSpi

Stream cipher service provider interface (SPI) implementation.

A stream cipher encrypts or decrypts a stream of data, one word at a time. A "word" of input is a fixed number of bits wide, and can be as small as one bit or as large as 64 bits. Generally, stream ciphers are used to encrypt single 8-bit bytes (octets), or 32-bit or 64-bit blocks.

At the heart of a stream cipher engine is a symmetric block cipher. The stream cipher is initialized with an initial vector (IV) which is the same width as the underlying block cipher. The state of the stream cipher is filled with the IV value prior to encrypting any data from the input stream. The IV should be a random value, but it does not have to be kept secret; in fact, it is typically prepended to the encrypted output data stream or otherwise transmitted along with the encrypted data, so that the decrypting side uses the same IV value.

At each stage in the stream ciphering process, the state of the cipher is represented by a block of data the same width as the block size of the underlying block cipher. For each input word that is encrypted by the stream cipher, the state block is encrypted using the block cipher and the encryption key set up for the cipher. The rightmost N bits of the block encryption are then exclusive-or'd with the next N-bit input (plaintext) word, and the resulting (ciphertext) word is the next word of output from the stream cipher. The state block is then updated by shifting it N bits left and inserting either the N-bit ciphertext output word (in CFB mode) or the rightmost N bits of the block encryption (in OFB mode) in preparation for the next word.

Thus any fixed-width symmetric block cipher can be used as the underlying block cipher in a stream cipher.

The following stream encryption modes are supported:

The only padding scheme supported is "NoPadding" (CipherSpi.PADDING_NONE), since every input word (byte) results in the generation of an output word (byte), and therefore no input padding is necessary.

Note that none of these methods are synchronized.

Since:
2005-07-05
Version:
API 2, $Revision: 1.4 $ $Date: 2006/04/18 03:00:30 $
Author:
David R. Tribble (david@tribble.com).

Copyright 2005-2006 by David R. Tribble, all rights reserved.
Permission is granted to freely use and distribute this source code provided that the original copyright and authorship notices remain intact.

See Also:
BlockCipherSpi, AbstractCipher

Field Summary
static int SERIES
          Class series version.
 
Fields inherited from class tribble.crypto.CipherSpi
DECRYPT_MODE, ENCRYPT_MODE, MODE_BC, MODE_CBC, MODE_CFB, MODE_CFB8, MODE_CTR, MODE_CTR8, MODE_ECB, MODE_OFB, MODE_OFB8, MODE_PBC, MODE_PCBC, MODE_PFB, MODE_PFB8, PADDING_CTS, PADDING_NONE, PADDING_PKCS5, PADDING_ZEROS
 
Constructor Summary
protected StreamCipherSpi(SymmetricCipher ciph, java.lang.String mode, java.lang.String pad)
          Constructor.
 
Method Summary
protected  void engineClear()
          Clear (wipe) this cipher.
protected  byte[] engineDoFinal(byte[] in, int off, int len)
          Add final input bytes to this cipher.
protected  int engineDoFinal(byte[] in, int inOff, int len, byte[] out, int outOff)
          Add final input bytes to this cipher.
protected  int engineGetKeySize(java.security.Key key)
          Determine the size of a key for this cipher.
protected  int engineGetOutputSize(int n)
          Determine the output buffer size of this cipher.
protected  java.security.AlgorithmParameters engineGetParameters()
          Retrieve algorithm-specific initialization parameters for this cipher.
protected  void engineInit(int mode, java.security.Key key, java.security.spec.AlgorithmParameterSpec parms, java.security.SecureRandom rand)
          Initialize this cipher.
protected  void engineInit(int mode, java.security.Key key, java.security.AlgorithmParameters parms, java.security.SecureRandom rand)
          Initialize this cipher.
protected  void engineInit(int mode, java.security.Key key, java.security.SecureRandom rand)
          Initialize this cipher.
protected  void engineSetIV(byte[] iv)
          Set the initial vector (IV) used by this cipher.
protected  void engineSetMode(java.lang.String mode)
          Set the operating mode of this cipher.
protected  void engineSetPadding(java.lang.String padding)
          Set the padding scheme of this cipher.
protected  java.security.Key engineUnwrap(byte[] wrappedKey, java.lang.String alg, int type)
          Unwrap a cipher key from a raw encoded form.
protected  int engineUpdate(byte[] in, int inOff, int len, byte[] out, int outOff)
          Encrypt/decrypt an array of bytes using this cipher.
protected  byte[] engineWrap(java.security.Key key)
          Wrap a cipher key into a raw encoded form.
protected static void run(StreamCipherSpi ciph, java.lang.String[] args)
          Encrypt/decrypt a data file.
 
Methods inherited from class tribble.crypto.CipherSpi
engineGetBlockSize, engineGetIV, engineGetKeySize, engineUpdate, finalize
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

SERIES

public static final int SERIES
Class series version.

See Also:
Constant Field Values
Constructor Detail

StreamCipherSpi

protected StreamCipherSpi(SymmetricCipher ciph,
                          java.lang.String mode,
                          java.lang.String pad)
                   throws java.security.NoSuchAlgorithmException,
                          javax.crypto.NoSuchPaddingException
Constructor.

Parameters:
ciph - Underlying block cipher.
mode - Operating mode, which must match one of the MODE_XXX constants.
pad - Padding scheme, which must match one of the PADDING_XXX constants}.
Throws:
java.security.NoSuchAlgorithmException - Thrown if mode does not specify a supported operating mode.
javax.crypto.NoSuchPaddingException - Thrown if pad does not specify a supported padding scheme.
Since:
1.1, 2005-07-07
Method Detail

run

protected static void run(StreamCipherSpi ciph,
                          java.lang.String[] args)
                   throws java.lang.Exception
Encrypt/decrypt a data file.

Usage java tribble.crypto.SomeCipher [-option...] in-file

Options:

-e
Encrypt the input file.
-d
Decrypt the intput file.
-h
If encrypting, include information about the input file (modification date) in the encrypted output. If decrypting, extract the file information from the decrypted output and set the output file attributes (modification date) accordingly.
-o out-file
Output file. If this option is not specified, the output is written to the standard output by default.
-p passphrase
Encryption/decryption passphrase.
-pf passphrase-file
Text file containing the encryption/decryption passphrase.

Either the -e or the -d must be specified.

If neither the -p nor the -pf option is specified, the encryption/decryption passphrase is read from the standard input after a prompt is written to the standard error output.

Parameters:
ciph - Derived class cipher object to test.
args - Command line arguments.
Throws:
java.lang.Exception - Thrown if an error occurs in the encryption engine.
Since:
1.5, 2005-04-07

engineInit

protected void engineInit(int mode,
                          java.security.Key key,
                          java.security.SecureRandom rand)
                   throws java.security.InvalidKeyException
Initialize this cipher.

This method invokes the #initialize method of the underlying block cipher.

Specified by:
engineInit in class CipherSpi
Parameters:
mode - Ciphering mode, which is either CipherSpi.ENCRYPT_MODE or CipherSpi.DECRYPT_MODE.
key - Symmetric (secret) key for this cipher to use.
rand - Source of random values, or null if they are to be supplied by a default source.
Throws:
java.security.InvalidKeyException - Thrown if key is not the proper kind of key for use with this cipher.
java.lang.IllegalArgumentException - (unchecked) Thrown if mode is not a valid value.
Since:
1.1, 2005-07-07
See Also:
engineGetParameters(), engineGetIV(), engineSetIV(), #initialize

engineInit

protected void engineInit(int mode,
                          java.security.Key key,
                          java.security.spec.AlgorithmParameterSpec parms,
                          java.security.SecureRandom rand)
                   throws java.security.InvalidKeyException,
                          java.security.InvalidAlgorithmParameterException
Initialize this cipher.

This method invokes the initialize() method of the underlying cipher.

Note that if this cipher is being initialized for decryption, it must be provided with the same algorithm parameters that were used to initialize the cipher that originally encrypted the data that will be fed into this cipher.

Specified by:
engineInit in class CipherSpi
Parameters:
mode - Ciphering mode, which is either CipherSpi.ENCRYPT_MODE or CipherSpi.DECRYPT_MODE.
key - Key for this cipher to use.
parms - Algorithm-specific initialization parameters (e.g., an IV passed as a javax.crypto.spec.IvParameterSpec object). If this parameter is null and mode is ENCRYPT_MODE, the IV is initialized from the random source rand; otherwise if mode is DECRYPT_MODE, the IV is initialized to all zeros.
rand - Source of random values, or null if this is to be supplied by a default source.
Throws:
java.security.InvalidKeyException - Thrown if key is not the proper kind of key (i.e., a javax.crypto.spec.SecretKeySpec) for use with this cipher.
java.security.InvalidAlgorithmParameterException - Thrown if parms is not a proper initialization parameter for this cipher.
java.lang.IllegalArgumentException - (unchecked) Thrown if mode is not a valid value.
Since:
1.1, 2005-07-07
See Also:
engineGetParameters(), engineGetIV(), engineSetIV()

engineInit

protected void engineInit(int mode,
                          java.security.Key key,
                          java.security.AlgorithmParameters parms,
                          java.security.SecureRandom rand)
                   throws java.security.InvalidKeyException,
                          java.security.InvalidAlgorithmParameterException
Initialize this cipher.

This method invokes the initialize() method of the underlying cipher.

Note that if this cipher is being initialized for decryption, it must be provided with the same algorithm parameters that were used to initialize the cipher that originally encrypted the data that will be fed into this cipher.

Specified by:
engineInit in class CipherSpi
Parameters:
mode - Ciphering mode, which is either CipherSpi.ENCRYPT_MODE or CipherSpi.DECRYPT_MODE.
key - Key for this cipher to use.
parms - Algorithm-specific initialization parameters (e.g., an IV passed as a javax.crypto.spec.IvParameterSpec object).
rand - Source of random values, or null if this is to be supplied by a default source.
Throws:
java.security.InvalidKeyException - Thrown if key is not the proper kind of key for use with this cipher.
java.security.InvalidAlgorithmParameterException - Thrown if parms is not a proper initialization parameter for this cipher.
Since:
1.1, 2005-07-07
See Also:
engineGetParameters(), engineGetIV(), engineSetIV()

engineSetMode

protected void engineSetMode(java.lang.String mode)
                      throws java.security.NoSuchAlgorithmException
Set the operating mode of this cipher.

Specified by:
engineSetMode in class CipherSpi
Parameters:
mode - Cipher operating mode to use (e.g., "CFB", "OFB", "CTR", etc.). The default mode is "CFB". See the MODE_XXX constants.
Throws:
java.security.NoSuchAlgorithmException - Thrown if mode does not specify a operating mode supported by this cipher.
java.lang.NullPointerException - (unchecked) Thrown if mode is null.
Since:
1.1, 2005-07-07

engineSetPadding

protected void engineSetPadding(java.lang.String padding)
                         throws javax.crypto.NoSuchPaddingException
Set the padding scheme of this cipher.

Specified by:
engineSetPadding in class CipherSpi
Parameters:
padding - Cipher padding scheme to use. Note that the only padding supported in stream mode is "NoPadding" (CipherSpi.PADDING_NONE), which is the default scheme. See the PADDING_XXX constants.
Throws:
javax.crypto.NoSuchPaddingException - Thrown if padding does not specify a padding scheme supported by this cipher.
java.lang.NullPointerException - (unchecked) Thrown if padding is null.
Since:
1.1, 2005-07-07

engineSetIV

protected void engineSetIV(byte[] iv)
                    throws java.security.InvalidAlgorithmParameterException
Set the initial vector (IV) used by this cipher.

This method is not part of the standard set defined in class javax.crypto.CipherSpi, but is provided as a convenient enhancement.

Overrides:
engineSetIV in class CipherSpi
Parameters:
iv - Initial vector bytes to be used by this cipher. This array must be no longer than the cipher block size (see CipherSpi.engineGetBlockSize()). It can be shorter than the cipher block size, in which case the IV of this cipher will be padded on the right with zeros. Note that the contents of this array are copied to an internal buffer, so that subsequent changes made to the array do not affect this cipher object.
Throws:
java.security.InvalidAlgorithmParameterException - Thrown if the length of iv is longer than the cipher block size.
java.lang.NullPointerException - (unchecked) Thrown if iv is null.
Since:
1.1, 2005-07-08

engineGetKeySize

protected int engineGetKeySize(java.security.Key key)
                        throws java.security.InvalidKeyException
Determine the size of a key for this cipher.

Overrides:
engineGetKeySize in class CipherSpi
Parameters:
key - A key suitable for use with this cipher.
Returns:
Key size (in bits) of the given key.
Throws:
java.security.InvalidKeyException - Thrown if the given key cannot be used with this cipher.
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
java.lang.UnsupportedOperationException - (unchecked) Thrown if this method is not overridden.
java.lang.NullPointerException - (unchecked) Thrown if key is null.
Since:
1.1, 2005-07-07

engineGetOutputSize

protected int engineGetOutputSize(int n)
Determine the output buffer size of this cipher.

Specified by:
engineGetOutputSize in class CipherSpi
Parameters:
n - Size of the input buffer.
Returns:
Output buffer size (in bytes) that will be created by this cipher. For stream ciphers, this is always equal to n, the input buffer size.
Throws:
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
Since:
1.1, 2005-07-07

engineGetParameters

protected java.security.AlgorithmParameters engineGetParameters()
Retrieve algorithm-specific initialization parameters for this cipher.

Specified by:
engineGetParameters in class CipherSpi
Returns:
Algorithm-specific initialization parameters.
Throws:
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
Since:
1.1, 2005-07-07

engineUpdate

protected int engineUpdate(byte[] in,
                           int inOff,
                           int len,
                           byte[] out,
                           int outOff)
                    throws javax.crypto.ShortBufferException
Encrypt/decrypt an array of bytes using this cipher.

This method handles the operating modes and so forth required of stream ciphers.

Note that the length of the output is equal to the length of the input, regardless of the block size of the underlying block cipher.

Stream Encryption

                       +---------+
                   IV  |         |
                       +---------+
                            :
                            v
                State  +-------+-+
                Block  |       | | <-------+
                     i +-------+-+         :
                            :              :
                            v              :
                      +===========+        :
                      [           ]        :
        +-------+     [  Block    ]        :
    Key |       | --> [  Cipher   ]        :
        +-------+     [           ]        :
                      +===========+        :
                            :              :
                            v              :
             Encrypted +-+-------+         o  Mode
               Block   | |       |        /|\
                       +-+-------+       / | \
                        :               /  |  \
                        v              o   o   o
                       +-+             :   :   :
                   Ei  | | ------------+   :   :
                       +-+                 :   :
                        :                  :   :
                        v                  :  +-+
                     [ XOR ] ---------------> | | --> Output
                        ^                  :  +-+     Stream
                        :                  :   Ci
    Input              +-+                 :
    Stream  ---------> | | ----------------+
                       +-+
                        Pi 

Stream Decryption

                       +---------+
                   IV  |         |
                       +---------+
                            :
                            v
                State  +-------+-+
                Block  |       | | <-------+
                     i +-------+-+         :
                            :              :
                            v              :
                      +===========+        :
                      [           ]        :
        +-------+     [  Block    ]        :
    Key |       | --> [  Cipher   ]        :
        +-------+     [           ]        :
                      +===========+        :
                            :              :
                            v              :
             Encrypted +-+-------+         o  Mode
               Block   | |       |        /|\
                       +-+-------+       / | \
                        :               /  |  \
                        v              o   o   o
                       +-+             :   :   :
                   Ei  | | ------------+   :   :
                       +-+                 :   :
                        :                  :   :
                        v                  :  +-+
                     [ XOR ] ---------------> | | --> Output
                        ^                  :  +-+     Stream
                        :                  :   Pi
    Input              +-+                 :
    Stream  ---------> | | ----------------+
                       +-+
                        Ci 

Specified by:
engineUpdate in class CipherSpi
Parameters:
in - Array of bytes to encrypt/decrypt. The data from this array is appended to any input data previously added to this cipher.
inOff - Index of the first byte in array in to encrypt/decrypt.
len - Number of bytes in array in to encrypt/decrypt.
out - Resulting encrypted/decrypted output bytes.
outOff - Index of the first byte in array out to write the resulting output bytes to.
Returns:
Number of encrypted/decrypted bytes written into array out.
Throws:
javax.crypto.ShortBufferException - Thrown if the output buffer is too small to hold the resulting data.
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
java.lang.IllegalArgumentException - (unchecked) Thrown if len is negative.
Since:
1.1, 2005-07-07

engineDoFinal

protected byte[] engineDoFinal(byte[] in,
                               int off,
                               int len)
Add final input bytes to this cipher. The added bytes are encrypted/decrypted, being appended to any input bytes that were previously added to this cipher.

See engineDoFinal() for more details.

Overrides:
engineDoFinal in class CipherSpi
Parameters:
in - Array of bytes to add as input to this cipher.
off - Index of the first byte in array in to input to this cipher.
len - Number of bytes in array in to input to this cipher.
Returns:
Array of bytes suitably encrypted/decrypted by this cipher.
Throws:
java.lang.IllegalArgumentException - (unchecked) Thrown if len is negative.
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
Since:
1.1, 2005-07-07

engineDoFinal

protected int engineDoFinal(byte[] in,
                            int inOff,
                            int len,
                            byte[] out,
                            int outOff)
                     throws javax.crypto.ShortBufferException
Add final input bytes to this cipher. The added bytes are encrypted/decrypted, being appended to any input bytes that were previously added to this cipher.

See engineDoFinal() for more details.

Specified by:
engineDoFinal in class CipherSpi
Parameters:
in - Array of bytes to add as input to this cipher.
inOff - Index of the first byte in array in to input to this cipher.
len - Number of bytes in array in to input to this cipher.
out - Output array to write the resulting encrypted/decrypted bytes to.
outOff - Index of the first byte in array out to write the resulting output bytes to.
Returns:
Number of output bytes produced by this cipher.
Throws:
javax.crypto.ShortBufferException - Thrown if the output buffer is too small to hold the resulting data.
java.lang.IllegalArgumentException - (unchecked) Thrown if len is negative.
java.lang.IllegalStateException - (unchecked) Thrown if this cipher has not been initialized.
Since:
1.1, 2005-07-07

engineWrap

protected byte[] engineWrap(java.security.Key key)
                     throws javax.crypto.IllegalBlockSizeException,
                            java.security.InvalidKeyException
Wrap a cipher key into a raw encoded form.

Overrides:
engineWrap in class CipherSpi
Parameters:
key - Key suitable for use with this cipher.
Returns:
The key in a raw encoded format.
Throws:
javax.crypto.IllegalBlockSizeException - Thrown if key is not encoded with a block length supported by this cipher.
java.security.InvalidKeyException - Thrown if key is not a valid key for this cipher.
java.lang.UnsupportedOperationException - (unchecked) Thrown if this operation is not supported by this cipher.
Since:
1.1, 2005-09-09
See Also:
engineUnwrap()

engineUnwrap

protected java.security.Key engineUnwrap(byte[] wrappedKey,
                                         java.lang.String alg,
                                         int type)
                                  throws java.security.InvalidKeyException,
                                         java.security.NoSuchAlgorithmException
Unwrap a cipher key from a raw encoded form.

Overrides:
engineUnwrap in class CipherSpi
Returns:
The key, decoded into a form suitable for use with this cipher.
Throws:
java.security.InvalidKeyException - Thrown if key is not a valid key for this cipher.
java.security.NoSuchAlgorithmException - Thrown if key is not encoded in a recognizable form.
java.lang.UnsupportedOperationException - (unchecked) Thrown if this operation is not supported by this cipher.
Since:
1.1, 2005-09-09
See Also:
engineWrap()

engineClear

protected void engineClear()
Clear (wipe) this cipher. Erases all sensitive information contained within this object.

This method is not part of the standard set defined in class javax.crypto.CipherSpi, but is provided as a convenient enhancement.

Note that this cipher object is no longer usable after calling this method.

Overrides:
engineClear in class CipherSpi
Since:
1.1, 2005-07-05