org.apache.shiro.crypto
Class JcaCipherService

java.lang.Object
  extended by org.apache.shiro.crypto.JcaCipherService
All Implemented Interfaces:
CipherService
Direct Known Subclasses:
AbstractSymmetricCipherService

public abstract class JcaCipherService
extends Object
implements CipherService

Abstract CipherService implementation utilizing Java's JCA APIs.

Auto-generated Initialization Vectors

Shiro does something by default for all of its CipherService implementations that the JCA Cipher does not do: by default, initialization vectors are automatically randomly generated and prepended to encrypted data before returning from the encrypt methods. That is, the returned byte array or OutputStream is actually a concatenation of an initialization vector byte array plus the actual encrypted data byte array. The decrypt methods in turn know to read this prepended initialization vector before decrypting the real data that follows.

This is highly desirable because initialization vectors guarantee that, for a key and any plaintext, the encrypted output will always be different even if you call encrypt multiple times with the exact same arguments. This is essential in cryptography to ensure that data patterns cannot be identified across multiple input sources that are the same or similar.

You can turn off this behavior by setting the generateInitializationVectors property to false, but it is highly recommended that you do not do this unless you have a very good reason to do so, since you would be losing a critical security feature.

Initialization Vector Size

This implementation defaults the initializationVectorSize attribute to 128 bits, a fairly common size. Initialization vector sizes are very algorithm specific however, so subclass implementations will often override this value in their constructor if necessary.

Also note that initializationVectorSize values are specified in the number of bits (not bytes!) to match common references in most cryptography documentation. In practice though, initialization vectors are always specified as a byte array, so ensure that if you set this property, that the value is a multiple of 8 to ensure that the IV can be correctly represented as a byte array (the setInitializationVectorSize mutator method enforces this).

Since:
1.0

Constructor Summary
protected JcaCipherService(String algorithmName)
          Creates a new JcaCipherService instance which will use the specified cipher algorithmName for all encryption, decryption, and key operations.
 
Method Summary
 ByteSource decrypt(byte[] ciphertext, byte[] key)
          Decrypts encrypted data via the specified cipher key and returns the original (pre-encrypted) data.
 void decrypt(InputStream in, OutputStream out, byte[] key)
          Receives encrypted data from the given InputStream, decrypts it, and sends the resulting decrypted data to the given OutputStream.
 ByteSource encrypt(byte[] plaintext, byte[] key)
          Encrypts data via the specified cipher key.
 void encrypt(InputStream in, OutputStream out, byte[] key)
          Receives the data from the given InputStream, encrypts it, and sends the resulting encrypted data to the given OutputStream.
protected  SecureRandom ensureSecureRandom()
           
protected  byte[] generateInitializationVector(boolean streaming)
           
 String getAlgorithmName()
          Returns the cipher algorithm name that will be used for all encryption, decryption, and key operations (for example, 'AES', 'Blowfish', 'RSA', 'DSA', 'TripleDES', etc).
protected static SecureRandom getDefaultSecureRandom()
           
 int getInitializationVectorSize()
          Returns the algorithm-specific size in bits of generated initialization vectors.
 int getKeySize()
          Returns the size in bits (not bytes) of generated cipher keys.
 SecureRandom getSecureRandom()
          Returns a source of randomness for encryption operations.
 int getStreamingBufferSize()
          Returns the size in bytes of the internal buffer used to transfer data from one stream to another during stream operations (encrypt(java.io.InputStream, java.io.OutputStream, byte[]) and decrypt(java.io.InputStream, java.io.OutputStream, byte[])).
protected  String getTransformationString(boolean streaming)
          Returns the transformation string to use with the Cipher.getInstance(java.lang.String) invocation when creating a new Cipher instance.
 boolean isGenerateInitializationVectors()
           
protected  boolean isGenerateInitializationVectors(boolean streaming)
           
 void setGenerateInitializationVectors(boolean generateInitializationVectors)
           
 void setInitializationVectorSize(int initializationVectorSize)
          Sets the algorithm-specific initialization vector size in bits (not bytes!) to be used when generating initialization vectors.
 void setKeySize(int keySize)
          Sets the size in bits (not bytes) of generated cipher keys.
 void setSecureRandom(SecureRandom secureRandom)
          Sets a source of randomness for encryption operations.
 void setStreamingBufferSize(int streamingBufferSize)
          Sets the size in bytes of the internal buffer used to transfer data from one stream to another during stream operations (encrypt(java.io.InputStream, java.io.OutputStream, byte[]) and decrypt(java.io.InputStream, java.io.OutputStream, byte[])).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

JcaCipherService

protected JcaCipherService(String algorithmName)
Creates a new JcaCipherService instance which will use the specified cipher algorithmName for all encryption, decryption, and key operations. Also, the following defaults are set:

Parameters:
algorithmName - the name of the cipher algorithm to use for all encryption, decryption, and key operations
Method Detail

getAlgorithmName

public String getAlgorithmName()
Returns the cipher algorithm name that will be used for all encryption, decryption, and key operations (for example, 'AES', 'Blowfish', 'RSA', 'DSA', 'TripleDES', etc).

Returns:
the cipher algorithm name that will be used for all encryption, decryption, and key operations

getKeySize

public int getKeySize()
Returns the size in bits (not bytes) of generated cipher keys.

Returns:
the size in bits (not bytes) of generated cipher keys.

setKeySize

public void setKeySize(int keySize)
Sets the size in bits (not bytes) of generated cipher keys.

Parameters:
keySize - the size in bits (not bytes) of generated cipher keys.

isGenerateInitializationVectors

public boolean isGenerateInitializationVectors()

setGenerateInitializationVectors

public void setGenerateInitializationVectors(boolean generateInitializationVectors)

getInitializationVectorSize

public int getInitializationVectorSize()
Returns the algorithm-specific size in bits of generated initialization vectors.

Returns:
the algorithm-specific size in bits of generated initialization vectors.

setInitializationVectorSize

public void setInitializationVectorSize(int initializationVectorSize)
                                 throws IllegalArgumentException
Sets the algorithm-specific initialization vector size in bits (not bytes!) to be used when generating initialization vectors. The value must be a multiple of 8 to ensure that the IV can be represented as a byte array.

Parameters:
initializationVectorSize - the size in bits (not bytes) of generated initialization vectors.
Throws:
IllegalArgumentException - if the size is not a multiple of 8.

isGenerateInitializationVectors

protected boolean isGenerateInitializationVectors(boolean streaming)

getStreamingBufferSize

public int getStreamingBufferSize()
Returns the size in bytes of the internal buffer used to transfer data from one stream to another during stream operations (encrypt(java.io.InputStream, java.io.OutputStream, byte[]) and decrypt(java.io.InputStream, java.io.OutputStream, byte[])).

Default size is 512 bytes.

Returns:
the size of the internal buffer used to transfer data from one stream to another during stream operations

setStreamingBufferSize

public void setStreamingBufferSize(int streamingBufferSize)
Sets the size in bytes of the internal buffer used to transfer data from one stream to another during stream operations (encrypt(java.io.InputStream, java.io.OutputStream, byte[]) and decrypt(java.io.InputStream, java.io.OutputStream, byte[])).

Default size is 512 bytes.

Parameters:
streamingBufferSize - the size of the internal buffer used to transfer data from one stream to another during stream operations

getSecureRandom

public SecureRandom getSecureRandom()
Returns a source of randomness for encryption operations. If one is not configured, and the underlying algorithm needs one, the JDK SHA1PRNG instance will be used by default.

Returns:
a source of randomness for encryption operations. If one is not configured, and the underlying algorithm needs one, the JDK SHA1PRNG instance will be used by default.

setSecureRandom

public void setSecureRandom(SecureRandom secureRandom)
Sets a source of randomness for encryption operations. If one is not configured, and the underlying algorithm needs one, the JDK SHA1PRNG instance will be used by default.

Parameters:
secureRandom - a source of randomness for encryption operations. If one is not configured, and the underlying algorithm needs one, the JDK SHA1PRNG instance will be used by default.

getDefaultSecureRandom

protected static SecureRandom getDefaultSecureRandom()

ensureSecureRandom

protected SecureRandom ensureSecureRandom()

getTransformationString

protected String getTransformationString(boolean streaming)
Returns the transformation string to use with the Cipher.getInstance(java.lang.String) invocation when creating a new Cipher instance. This default implementation always returns getAlgorithmName(). Block cipher implementations will want to override this method to support appending cipher operation modes and padding schemes.

Parameters:
streaming - if the transformation string is going to be used for a Cipher for stream-based encryption or not.
Returns:
the transformation string to use with the Cipher.getInstance(java.lang.String) invocation when creating a new Cipher instance.

generateInitializationVector

protected byte[] generateInitializationVector(boolean streaming)

encrypt

public ByteSource encrypt(byte[] plaintext,
                          byte[] key)
Description copied from interface: CipherService
Encrypts data via the specified cipher key. Note that the key must be in a format understood by the CipherService implementation.

Specified by:
encrypt in interface CipherService
Parameters:
plaintext - the data to encrypt
key - the cipher key used during encryption.
Returns:
a byte source with the encrypted representation of the specified raw data.

decrypt

public ByteSource decrypt(byte[] ciphertext,
                          byte[] key)
                   throws CryptoException
Description copied from interface: CipherService
Decrypts encrypted data via the specified cipher key and returns the original (pre-encrypted) data. Note that the key must be in a format understood by the CipherService implementation.

Specified by:
decrypt in interface CipherService
Parameters:
ciphertext - the previously encrypted data to decrypt
key - the cipher key used during decryption.
Returns:
a byte source representing the original form of the specified encrypted data.
Throws:
CryptoException - if there is an error during decryption

encrypt

public void encrypt(InputStream in,
                    OutputStream out,
                    byte[] key)
             throws CryptoException
Description copied from interface: CipherService
Receives the data from the given InputStream, encrypts it, and sends the resulting encrypted data to the given OutputStream.

NOTE: This method does NOT flush or close either stream prior to returning - the caller must do so when they are finished with the streams. For example:

 try {
     InputStream in = ...
     OutputStream out = ...
     cipherService.encrypt(in, out, encryptionKey);
 } finally {
     if (in != null) {
         try {
             in.close();
         } catch (IOException ioe1) { ... log, trigger event, etc }
     }
     if (out != null) {
         try {
             out.close();
         } catch (IOException ioe2) { ... log, trigger event, etc }
     }
 }
 

Specified by:
encrypt in interface CipherService
Parameters:
in - the stream supplying the data to encrypt
out - the stream to send the encrypted data
key - the cipher key to use for encryption
Throws:
CryptoException - if there is any problem during encryption.

decrypt

public void decrypt(InputStream in,
                    OutputStream out,
                    byte[] key)
             throws CryptoException
Description copied from interface: CipherService
Receives encrypted data from the given InputStream, decrypts it, and sends the resulting decrypted data to the given OutputStream.

NOTE: This method does NOT flush or close either stream prior to returning - the caller must do so when they are finished with the streams. For example:

 try {
     InputStream in = ...
     OutputStream out = ...
     cipherService.decrypt(in, out, decryptionKey);
 } finally {
     if (in != null) {
         try {
             in.close();
         } catch (IOException ioe1) { ... log, trigger event, etc }
     }
     if (out != null) {
         try {
             out.close();
         } catch (IOException ioe2) { ... log, trigger event, etc }
     }
 }
 

Specified by:
decrypt in interface CipherService
Parameters:
in - the stream supplying the data to decrypt
out - the stream to send the decrypted data
key - the cipher key to use for decryption
Throws:
CryptoException - if there is any problem during decryption.


Copyright © 2004-2012 The Apache Software Foundation. All Rights Reserved.