Class DefaultBlockCipherService

  • All Implemented Interfaces:
    CipherService
    Direct Known Subclasses:
    AesCipherService, BlowfishCipherService

    public class DefaultBlockCipherService
    extends AbstractSymmetricCipherService
    Base abstract class for block cipher algorithms.

    Usage

    Note that this class exists mostly to simplify algorithm-specific subclasses. Unless you understand the concepts of cipher modes of operation, block sizes, and padding schemes, and you want direct control of these things, you should typically not uses instances of this class directly. Instead, algorithm-specific subclasses, such as AesCipherService, BlowfishCipherService, and others are usually better suited for regular use.

    However, if you have the need to create a custom block cipher service where no sufficient algorithm-specific subclass exists in Shiro, this class would be very useful.

    Configuration

    Block ciphers can accept configuration parameters that direct how they operate. These parameters concatenated together in a single String comprise what the JDK JCA documentation calls a transformation string. We think that it is better for Shiro to construct this transformation string automatically based on its constituent parts instead of having the end-user construct the string manually, which may be error prone or confusing. To that end, Shiro DefaultBlockCipherServices have attributes that can be set individually in a type-safe manner based on your configuration needs, and Shiro will build the transformation string for you.

    The following sections typically document the configuration options for block (byte array) JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[]) method invocations. Streaming configuration for those same attributes are done via mirrored streaming* attributes, and their purpose is identical, but they're only used during streaming JcaCipherService.encrypt(java.io.InputStream, java.io.OutputStream, byte[]) and JcaCipherService.decrypt(java.io.InputStream, java.io.OutputStream, byte[]) methods. See the "Streaming" section below for more.

    Block Size

    The block size specifies the number of bits (not bytes) that the cipher operates on when performing an operation. It can be specified explicitly via the blockSize attribute. If not set, the JCA Provider default will be used based on the cipher algorithm. Block sizes are usually very algorithm specific, so set this value only if you know you don't want the JCA Provider's default for the desired algorithm. For example, the AES algorithm's Rijndael implementation only supports a 128 bit block size and will not work with any other size.

    Also note that the initializationVectorSize is usually the same as the blockSize in block ciphers. If you change either attribute, you should ensure that the other attribute is correct for the target cipher algorithm.

    Operation Mode

    You may set the block cipher'smode of operation via the mode attribute, which accepts a type-safe OperationMode enum instance. This type safety helps avoid typos when specifying the mode and guarantees that the mode name will be recognized by the underlying JCA Provider.

    *If no operation mode is specified, Shiro defaults all of its block CipherService instances to the CBC mode, specifically to support auto-generation of initialization vectors during encryption. This is different than the JDK's default ECB mode because ECB does not support initialization vectors, which are necessary for strong encryption. See the JcaCipherService parent class class JavaDoc for an extensive explanation on why we do this and why we do not use the Sun ECB default. You also might also want read the Wikipedia section on ECB and look at the encrypted image to see an example of why ECB should not be used in security-sensitive environments.

    In the rare case that you need to override the default with a mode not represented by the OperationMode enum, you may specify the raw mode name string that will be recognized by your JCA provider via the modeName attribute. Because this is not type-safe, it is recommended only to use this attribute if the OperationMode enum does not represent your desired mode.

    NOTE: If you change the mode to one that does not support initialization vectors (such as ECB or NONE), you must turn off auto-generated initialization vectors by setting generateInitializationVectors to false. Abandoning initialization vectors significantly weakens encryption, so think twice before disabling this feature.

    Padding Scheme

    Because block ciphers process messages in fixed-length blocks, if the final block in a message is not equal to the block length, padding is applied to match that size to maintain the total length of the message. This is good because it protects data patterns from being identified - when all chunks look the same length, it is much harder to infer what that data might be.

    You may set a padding scheme via the paddingScheme attribute, which accepts a type-safe PaddingScheme enum instance. Like the OperationMode enum, this enum offers type safety to help avoid typos and guarantees that the mode will be recongized by the underlying JCA provider.

    *If no padding scheme is specified, this class defaults to the PaddingScheme.PKCS5 scheme, specifically to be compliant with the default behavior of auto-generating initialization vectors during encryption (see the JcaCipherService parent class class JavaDoc for why).

    In the rare case that you need to override the default with a scheme not represented by the PaddingScheme enum, you may specify the raw padding scheme name string that will be recognized by your JCA provider via the paddingSchemeName attribute. Because this is not type-safe, it is recommended only to use this attribute if the PaddingScheme enum does not represent your desired scheme.

    Streaming

    Most people don't think of using block ciphers as stream ciphers, since their name implies working with block data (i.e. byte arrays) only. However, block ciphers can be turned into byte-oriented stream ciphers by using an appropriate operation mode with a streaming block size of 8 bits. This is why the CipherService interface provides both block and streaming operations.

    Because this streaming 8-bit block size rarely changes across block-cipher algorithms, default values have been set for all three streaming configuration parameters. The defaults are:

    These attributes have the same meaning as the mode, blockSize, and paddingScheme attributes described above, but they are applied during streaming method invocations only (JcaCipherService.encrypt(java.io.InputStream, java.io.OutputStream, byte[]) and JcaCipherService.decrypt(java.io.InputStream, java.io.OutputStream, byte[])).

    Since:
    1.0
    See Also:
    BlowfishCipherService, AesCipherService, Wikipedia: Block Cipher Modes of Operation
    • Constructor Detail

      • DefaultBlockCipherService

        public DefaultBlockCipherService​(String algorithmName)
        Creates a new DefaultBlockCipherService using the specified block cipher algorithmName. Per this class's JavaDoc, this constructor also sets the following defaults:
        • streamingMode = CBC
        • streamingPaddingScheme = none
        • streamingBlockSize = 8
        All other attributes are null/unset, indicating the JCA Provider defaults will be used.
        Parameters:
        algorithmName - the block cipher algorithm to use when encrypting and decrypting
    • Method Detail

      • getModeName

        public String getModeName()
        Returns the cipher operation mode name (as a String) to be used when constructing Cipher transformation string or null if the JCA Provider default mode for the specified algorithm should be used.

        This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[])). The streamingModeName attribute is used when the block cipher is used for streaming operations.

        The default value is null to retain the JCA Provider default.

        Returns:
        the cipher operation mode name (as a String) to be used when constructing the Cipher transformation string, or null if the JCA Provider default mode for the specified algorithm should be used.
      • setModeName

        public void setModeName​(String modeName)
        Sets the cipher operation mode name to be used when constructing the Cipher transformation string. A null value indicates that the JCA Provider default mode for the specified algorithm should be used.

        This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[])). The streamingModeName attribute is used when the block cipher is used for streaming operations.

        The default value is null to retain the JCA Provider default.

        NOTE: most standard mode names are represented by the OperationMode enum. That enum should be used with the mode attribute when possible to retain type-safety and reduce the possibility of errors. This method is better used if the OperationMode enum does not represent the necessary mode.

        Parameters:
        modeName - the cipher operation mode name to be used when constructing Cipher transformation string, or null if the JCA Provider default mode for the specified algorithm should be used.
        See Also:
        setMode(org.apache.shiro.crypto.OperationMode)
      • setMode

        public void setMode​(OperationMode mode)
        Sets the cipher operation mode of operation to be used when constructing the Cipher transformation string. A null value indicates that the JCA Provider default mode for the specified algorithm should be used.

        This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[])). The streamingMode attribute is used when the block cipher is used for streaming operations.

        If the OperationMode enum cannot represent your desired mode, you can set the name explicitly via the modeName attribute directly. However, because OperationMode represents all standard JDK mode names already, ensure that your underlying JCA Provider supports the non-standard name first.

        Parameters:
        mode - the cipher operation mode to be used when constructing Cipher transformation string, or null if the JCA Provider default mode for the specified algorithm should be used.
      • getPaddingSchemeName

        public String getPaddingSchemeName()
        Returns the cipher algorithm padding scheme name (as a String) to be used when constructing Cipher transformation string or null if the JCA Provider default mode for the specified algorithm should be used.

        This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[])). The streamingPaddingSchemeName attribute is used when the block cipher is used for streaming operations.

        The default value is null to retain the JCA Provider default.

        Returns:
        the padding scheme name (as a String) to be used when constructing the Cipher transformation string, or null if the JCA Provider default padding scheme for the specified algorithm should be used.
      • setPaddingSchemeName

        public void setPaddingSchemeName​(String paddingSchemeName)
        Sets the padding scheme name to be used when constructing the Cipher transformation string, or null if the JCA Provider default mode for the specified algorithm should be used.

        This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[])). The streamingPaddingSchemeName attribute is used when the block cipher is used for streaming operations.

        The default value is null to retain the JCA Provider default.

        NOTE: most standard padding schemes are represented by the PaddingScheme enum. That enum should be used with the paddingScheme attribute when possible to retain type-safety and reduce the possibility of errors. Calling this method however is suitable if the PaddingScheme enum does not represent the desired scheme.

        Parameters:
        paddingSchemeName - the padding scheme name to be used when constructing Cipher transformation string, or null if the JCA Provider default padding scheme for the specified algorithm should be used.
        See Also:
        setPaddingScheme(org.apache.shiro.crypto.PaddingScheme)
      • setPaddingScheme

        public void setPaddingScheme​(PaddingScheme paddingScheme)
        Sets the padding scheme to be used when constructing the Cipher transformation string. A null value indicates that the JCA Provider default padding scheme for the specified algorithm should be used.

        This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[])). The streamingPaddingScheme attribute is used when the block cipher is used for streaming operations.

        If the PaddingScheme enum does represent your desired scheme, you can set the name explicitly via the paddingSchemeName attribute directly. However, because PaddingScheme represents all standard JDK scheme names already, ensure that your underlying JCA Provider supports the non-standard name first.

        Parameters:
        paddingScheme - the padding scheme to be used when constructing Cipher transformation string, or null if the JCA Provider default padding scheme for the specified algorithm should be used.
      • getBlockSize

        public int getBlockSize()
        Returns the block cipher's block size to be used when constructing Cipher transformation string or 0 if the JCA Provider default block size for the specified algorithm should be used.

        This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[])). The streamingBlockSize attribute is used when the block cipher is used for streaming operations.

        The default value is 0 which retains the JCA Provider default.

        Returns:
        the block cipher block size to be used when constructing the Cipher transformation string, or 0 if the JCA Provider default block size for the specified algorithm should be used.
      • setBlockSize

        public void setBlockSize​(int blockSize)
        Sets the block cipher's block size to be used when constructing Cipher transformation string. 0 indicates that the JCA Provider default block size for the specified algorithm should be used.

        This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[]) and JcaCipherService.decrypt(byte[], byte[])). The streamingBlockSize attribute is used when the block cipher is used for streaming operations.

        The default value is 0 which retains the JCA Provider default.

        NOTE: block cipher block sizes are very algorithm-specific. If you change this value, ensure that it will work with the specified algorithm.

        Parameters:
        blockSize - the block cipher block size to be used when constructing the Cipher transformation string, or 0 if the JCA Provider default block size for the specified algorithm should be used.
      • setStreamingModeName

        public void setStreamingModeName​(String streamingModeName)
        Sets the transformation string mode name to be used for streaming operations only. The default value is CBC for reasons described in the class-level JavaDoc in the Streaming section.
        Parameters:
        streamingModeName - transformation string mode name to be used for streaming operations only
      • setStreamingMode

        public void setStreamingMode​(OperationMode mode)
        Sets the transformation string mode to be used for streaming operations only. The default value is CBC for reasons described in the class-level JavaDoc in the Streaming section.
        Parameters:
        mode - the transformation string mode to be used for streaming operations only
      • getTransformationString

        protected String getTransformationString​(boolean streaming)
        Returns the transformation string to use with the Cipher.getInstance(java.lang.String) call. If streaming is true, a block-cipher transformation string compatible with streaming operations will be constructed and cached for re-use later (see the class-level JavaDoc for more on using block ciphers for streaming). If streaming is false a normal block-cipher transformation string will be constructed and cached for later re-use.
        Overrides:
        getTransformationString in class JcaCipherService
        Parameters:
        streaming - if the transformation string is going to be used for a Cipher performing stream-based encryption or not.
        Returns:
        the transformation string
      • isGenerateInitializationVectors

        protected boolean isGenerateInitializationVectors​(boolean streaming)
        Overrides the parent implementation to ensure initialization vectors are always generated if streaming is enabled (block ciphers must use initialization vectors if they are to be used as a stream cipher). If not being used as a stream cipher, then the value is computed based on whether or not the currently configured modeName is compatible with initialization vectors as well as the result of the configured generateInitializationVectors value.
        Overrides:
        isGenerateInitializationVectors in class JcaCipherService
        Parameters:
        streaming - whether or not streaming is being performed
        Returns:
        true if streaming or a value computed based on if the currently configured mode is compatible with initialization vectors.