Package org.apache.shiro.crypto.cipher
Class DefaultBlockCipherService
java.lang.Object
org.apache.shiro.crypto.cipher.JcaCipherService
org.apache.shiro.crypto.cipher.AbstractSymmetricCipherService
org.apache.shiro.crypto.cipher.DefaultBlockCipherService
- All Implemented Interfaces:
CipherService
- Direct Known Subclasses:
AesCipherService,BlowfishCipherService
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 asAesCipherService, 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, ShiroDefaultBlockCipherServices 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 theblockSize 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 themode 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 thepaddingScheme 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 recognized 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 appropriateoperation 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:
streamingBlockSize=8(bits)streamingMode=CBCstreamingPaddingScheme=PKCS5
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:
-
Constructor Summary
ConstructorsConstructorDescriptionDefaultBlockCipherService(String algorithmName) Creates a newDefaultBlockCipherServiceusing the specified block cipheralgorithmName. -
Method Summary
Modifier and TypeMethodDescriptionprotected byte[]generateInitializationVector(boolean streaming) intintSame purpose as themodeNameattribute, but is used instead only for for streaming operations (JcaCipherService.encrypt(java.io.InputStream, java.io.OutputStream, byte[])andJcaCipherService.decrypt(java.io.InputStream, java.io.OutputStream, byte[])).protected StringgetTransformationString(boolean streaming) Returns the transformation string to use with theCipher.getInstance(java.lang.String)call.protected booleanisGenerateInitializationVectors(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).voidsetBlockSize(int blockSize) Sets the block cipher's block size to be used when constructingCiphertransformation string.voidsetMode(OperationMode mode) Sets the cipher operation mode of operation to be used when constructing theCiphertransformation string.voidsetModeName(String modeName) Sets the cipher operation mode name to be used when constructing theCiphertransformation string.voidsetPaddingScheme(PaddingScheme paddingScheme) Sets the padding scheme to be used when constructing theCiphertransformation string.voidsetPaddingSchemeName(String paddingSchemeName) voidsetStreamingBlockSize(int streamingBlockSize) voidSets the transformation string mode to be used for streaming operations only.voidsetStreamingModeName(String streamingModeName) Sets the transformation string mode name to be used for streaming operations only.voidvoidsetStreamingPaddingSchemeName(String streamingPaddingSchemeName) Methods inherited from class org.apache.shiro.crypto.cipher.AbstractSymmetricCipherService
generateNewKey, generateNewKeyMethods inherited from class org.apache.shiro.crypto.cipher.JcaCipherService
createParameterSpec, decrypt, decrypt, encrypt, encrypt, ensureSecureRandom, getAlgorithmName, getDefaultSecureRandom, getInitializationVectorSize, getKeySize, getSecureRandom, getStreamingBufferSize, isGenerateInitializationVectors, setGenerateInitializationVectors, setInitializationVectorSize, setKeySize, setSecureRandom, setStreamingBufferSize
-
Constructor Details
-
DefaultBlockCipherService
Creates a newDefaultBlockCipherServiceusing the specified block cipheralgorithmName. Per this class's JavaDoc, this constructor also sets the following defaults: 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 Details
-
getModeName
Returns the cipher operation mode name (as a String) to be used when constructingCiphertransformation string ornullif the JCA Provider default mode for the specifiedalgorithmshould be used. This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[])andJcaCipherService.decrypt(byte[], byte[])). ThestreamingModeNameattribute is used when the block cipher is used for streaming operations. The default value isnullto retain the JCA Provider default. -
setModeName
Sets the cipher operation mode name to be used when constructing theCiphertransformation string. Anullvalue indicates that the JCA Provider default mode for the specifiedalgorithmshould be used. This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[])andJcaCipherService.decrypt(byte[], byte[])). ThestreamingModeNameattribute is used when the block cipher is used for streaming operations. The default value isnullto retain the JCA Provider default. NOTE: most standard mode names are represented by theOperationModeenum. That enum should be used with themodeattribute when possible to retain type-safety and reduce the possibility of errors. This method is better used if theOperationModeenum does not represent the necessary mode. -
setMode
Sets the cipher operation mode of operation to be used when constructing theCiphertransformation string. Anullvalue indicates that the JCA Provider default mode for the specifiedalgorithmshould be used. This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[])andJcaCipherService.decrypt(byte[], byte[])). ThestreamingModeattribute is used when the block cipher is used for streaming operations. If theOperationModeenum cannot represent your desired mode, you can set the name explicitly via themodeNameattribute directly. However, becauseOperationModerepresents all standard JDK mode names already, ensure that your underlying JCA Provider supports the non-standard name first. -
getPaddingSchemeName
Returns the cipher algorithm padding scheme name (as a String) to be used when constructingCiphertransformation string ornullif the JCA Provider default mode for the specifiedalgorithmshould be used. This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[])andJcaCipherService.decrypt(byte[], byte[])). ThestreamingPaddingSchemeNameattribute is used when the block cipher is used for streaming operations. The default value isnullto retain the JCA Provider default. -
setPaddingSchemeName
Sets the padding scheme name to be used when constructing theCiphertransformation string, ornullif the JCA Provider default mode for the specifiedalgorithmshould be used. This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[])andJcaCipherService.decrypt(byte[], byte[])). ThestreamingPaddingSchemeNameattribute is used when the block cipher is used for streaming operations. The default value isnullto retain the JCA Provider default. NOTE: most standard padding schemes are represented by thePaddingSchemeenum. That enum should be used with thepaddingSchemeattribute when possible to retain type-safety and reduce the possibility of errors. Calling this method however is suitable if thePaddingSchemeenum does not represent the desired scheme. -
setPaddingScheme
Sets the padding scheme to be used when constructing theCiphertransformation string. Anullvalue indicates that the JCA Provider default padding scheme for the specifiedalgorithmshould be used. This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[])andJcaCipherService.decrypt(byte[], byte[])). ThestreamingPaddingSchemeattribute is used when the block cipher is used for streaming operations. If thePaddingSchemeenum does represent your desired scheme, you can set the name explicitly via thepaddingSchemeNameattribute directly. However, becausePaddingSchemerepresents all standard JDK scheme names already, ensure that your underlying JCA Provider supports the non-standard name first. -
getBlockSize
public int getBlockSize()Returns the block cipher's block size to be used when constructingCiphertransformation string or0if the JCA Provider default block size for the specifiedalgorithmshould be used. This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[])andJcaCipherService.decrypt(byte[], byte[])). ThestreamingBlockSizeattribute is used when the block cipher is used for streaming operations. The default value is0which retains the JCA Provider default. -
setBlockSize
public void setBlockSize(int blockSize) Sets the block cipher's block size to be used when constructingCiphertransformation string.0indicates that the JCA Provider default block size for the specifiedalgorithmshould be used. This attribute is used only when constructing the transformation string for block (byte array) operations (JcaCipherService.encrypt(byte[], byte[])andJcaCipherService.decrypt(byte[], byte[])). ThestreamingBlockSizeattribute is used when the block cipher is used for streaming operations. The default value is0which 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 specifiedalgorithm. -
getStreamingModeName
Same purpose as themodeNameattribute, but is used instead only for for streaming operations (JcaCipherService.encrypt(java.io.InputStream, java.io.OutputStream, byte[])andJcaCipherService.decrypt(java.io.InputStream, java.io.OutputStream, byte[])). Note that unlike themodeNameattribute, the default value of this attribute is notnull- it isCBCfor reasons described in the class-level JavaDoc in theStreamingsection.- Returns:
- the transformation string mode name to be used for streaming operations only.
-
setStreamingModeName
Sets the transformation string mode name to be used for streaming operations only. The default value isCBCfor reasons described in the class-level JavaDoc in theStreamingsection.- Parameters:
streamingModeName- transformation string mode name to be used for streaming operations only
-
setStreamingMode
Sets the transformation string mode to be used for streaming operations only. The default value isCBCfor reasons described in the class-level JavaDoc in theStreamingsection.- Parameters:
mode- the transformation string mode to be used for streaming operations only
-
getStreamingPaddingSchemeName
-
setStreamingPaddingSchemeName
-
setStreamingPaddingScheme
-
getStreamingBlockSize
public int getStreamingBlockSize() -
setStreamingBlockSize
public void setStreamingBlockSize(int streamingBlockSize) -
getTransformationString
Returns the transformation string to use with theCipher.getInstance(java.lang.String)call. Ifstreamingistrue, 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). Ifstreamingisfalsea normal block-cipher transformation string will be constructed and cached for later re-use.- Overrides:
getTransformationStringin classJcaCipherService- 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 configuredmodeNameis compatible with initialization vectors as well as the result of the configuredgenerateInitializationVectorsvalue.- Overrides:
isGenerateInitializationVectorsin classJcaCipherService- Parameters:
streaming- whether or not streaming is being performed- Returns:
trueif streaming or a value computed based on if the currently configured mode is compatible with initialization vectors.
-
generateInitializationVector
protected byte[] generateInitializationVector(boolean streaming) - Overrides:
generateInitializationVectorin classJcaCipherService
-