Package org.apache.shiro.crypto
Class DefaultBlockCipherService
- java.lang.Object
-
- org.apache.shiro.crypto.JcaCipherService
-
- org.apache.shiro.crypto.AbstractSymmetricCipherService
-
- org.apache.shiro.crypto.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 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, ShiroDefaultBlockCipherService
s 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[])
andJcaCipherService.decrypt(byte[], byte[])
method invocations. Streaming configuration for those same attributes are done via mirroredstreaming
* attributes, and their purpose is identical, but they're only used during streamingJcaCipherService.encrypt(java.io.InputStream, java.io.OutputStream, byte[])
andJcaCipherService.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 theinitializationVectorSize
is usually the same as theblockSize
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-safeOperationMode
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 blockCipherService
instances to theCBC
mode, specifically to support auto-generation of initialization vectors during encryption. This is different than the JDK's defaultECB
mode becauseECB
does not support initialization vectors, which are necessary for strong encryption. See theJcaCipherService parent class
class JavaDoc for an extensive explanation on why we do this and why we do not use the SunECB
default. You also might also want read the Wikipedia section on ECB and look at the encrypted image to see an example of whyECB
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 theOperationMode
enum, you may specify the raw mode name string that will be recognized by your JCA provider via themodeName
attribute. Because this is not type-safe, it is recommended only to use this attribute if theOperationMode
enum does not represent your desired mode. NOTE: If you change the mode to one that does not support initialization vectors (such asECB
orNONE
), you must turn off auto-generated initialization vectors by settinggenerateInitializationVectors
tofalse
. 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-safePaddingScheme
enum instance. Like theOperationMode
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 thePaddingScheme.PKCS5
scheme, specifically to be compliant with the default behavior of auto-generating initialization vectors during encryption (see theJcaCipherService parent class
class JavaDoc for why). In the rare case that you need to override the default with a scheme not represented by thePaddingScheme
enum, you may specify the raw padding scheme name string that will be recognized by your JCA provider via thepaddingSchemeName
attribute. Because this is not type-safe, it is recommended only to use this attribute if thePaddingScheme
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 astreaming block size
of 8 bits. This is why theCipherService
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
=CBC
streamingPaddingScheme
=PKCS5
mode
,blockSize
, andpaddingScheme
attributes described above, but they are applied during streaming method invocations only (JcaCipherService.encrypt(java.io.InputStream, java.io.OutputStream, byte[])
andJcaCipherService.decrypt(java.io.InputStream, java.io.OutputStream, byte[])
).- Since:
- 1.0
- See Also:
BlowfishCipherService
,AesCipherService
, Wikipedia: Block Cipher Modes of Operation
-
-
Constructor Summary
Constructors Constructor Description DefaultBlockCipherService(String algorithmName)
Creates a newDefaultBlockCipherService
using the specified block cipheralgorithmName
.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected byte[]
generateInitializationVector(boolean streaming)
int
getBlockSize()
String
getModeName()
String
getPaddingSchemeName()
int
getStreamingBlockSize()
String
getStreamingModeName()
Same purpose as themodeName
attribute, 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[])
).String
getStreamingPaddingSchemeName()
protected String
getTransformationString(boolean streaming)
Returns the transformation string to use with theCipher.getInstance(java.lang.String)
call.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).void
setBlockSize(int blockSize)
Sets the block cipher's block size to be used when constructingCipher
transformation string.void
setMode(OperationMode mode)
Sets the cipher operation mode of operation to be used when constructing theCipher
transformation string.void
setModeName(String modeName)
Sets the cipher operation mode name to be used when constructing theCipher
transformation string.void
setPaddingScheme(PaddingScheme paddingScheme)
Sets the padding scheme to be used when constructing theCipher
transformation string.void
setPaddingSchemeName(String paddingSchemeName)
void
setStreamingBlockSize(int streamingBlockSize)
void
setStreamingMode(OperationMode mode)
Sets the transformation string mode to be used for streaming operations only.void
setStreamingModeName(String streamingModeName)
Sets the transformation string mode name to be used for streaming operations only.void
setStreamingPaddingScheme(PaddingScheme scheme)
void
setStreamingPaddingSchemeName(String streamingPaddingSchemeName)
-
Methods inherited from class org.apache.shiro.crypto.AbstractSymmetricCipherService
generateNewKey, generateNewKey
-
Methods inherited from class org.apache.shiro.crypto.JcaCipherService
createParameterSpec, decrypt, decrypt, encrypt, encrypt, ensureSecureRandom, getAlgorithmName, getDefaultSecureRandom, getInitializationVectorSize, getKeySize, getSecureRandom, getStreamingBufferSize, isGenerateInitializationVectors, setGenerateInitializationVectors, setInitializationVectorSize, setKeySize, setSecureRandom, setStreamingBufferSize
-
-
-
-
Constructor Detail
-
DefaultBlockCipherService
public DefaultBlockCipherService(String algorithmName)
Creates a newDefaultBlockCipherService
using 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 Detail
-
getModeName
public String getModeName()
Returns the cipher operation mode name (as a String) to be used when constructingCipher
transformation string ornull
if the JCA Provider default mode for the specifiedalgorithm
should 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[])
). ThestreamingModeName
attribute is used when the block cipher is used for streaming operations. The default value isnull
to retain the JCA Provider default.
-
setModeName
public void setModeName(String modeName)
Sets the cipher operation mode name to be used when constructing theCipher
transformation string. Anull
value indicates that the JCA Provider default mode for the specifiedalgorithm
should 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[])
). ThestreamingModeName
attribute is used when the block cipher is used for streaming operations. The default value isnull
to retain the JCA Provider default. NOTE: most standard mode names are represented by theOperationMode
enum. That enum should be used with themode
attribute when possible to retain type-safety and reduce the possibility of errors. This method is better used if theOperationMode
enum does not represent the necessary mode.- Parameters:
modeName
- the cipher operation mode name to be used when constructingCipher
transformation string, ornull
if the JCA Provider default mode for the specifiedalgorithm
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 theCipher
transformation string. Anull
value indicates that the JCA Provider default mode for the specifiedalgorithm
should 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[])
). ThestreamingMode
attribute is used when the block cipher is used for streaming operations. If theOperationMode
enum cannot represent your desired mode, you can set the name explicitly via themodeName
attribute directly. However, becauseOperationMode
represents all standard JDK mode names already, ensure that your underlying JCA Provider supports the non-standard name first.
-
getPaddingSchemeName
public String getPaddingSchemeName()
Returns the cipher algorithm padding scheme name (as a String) to be used when constructingCipher
transformation string ornull
if the JCA Provider default mode for the specifiedalgorithm
should 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[])
). ThestreamingPaddingSchemeName
attribute is used when the block cipher is used for streaming operations. The default value isnull
to retain the JCA Provider default.
-
setPaddingSchemeName
public void setPaddingSchemeName(String paddingSchemeName)
Sets the padding scheme name to be used when constructing theCipher
transformation string, ornull
if the JCA Provider default mode for the specifiedalgorithm
should 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[])
). ThestreamingPaddingSchemeName
attribute is used when the block cipher is used for streaming operations. The default value isnull
to retain the JCA Provider default. NOTE: most standard padding schemes are represented by thePaddingScheme
enum. That enum should be used with thepaddingScheme
attribute when possible to retain type-safety and reduce the possibility of errors. Calling this method however is suitable if thePaddingScheme
enum does not represent the desired scheme.- Parameters:
paddingSchemeName
- the padding scheme name to be used when constructingCipher
transformation string, ornull
if the JCA Provider default padding scheme for the specifiedalgorithm
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 theCipher
transformation string. Anull
value indicates that the JCA Provider default padding scheme for the specifiedalgorithm
should 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[])
). ThestreamingPaddingScheme
attribute is used when the block cipher is used for streaming operations. If thePaddingScheme
enum does represent your desired scheme, you can set the name explicitly via thepaddingSchemeName
attribute directly. However, becausePaddingScheme
represents 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 constructingCipher
transformation string or0
if the JCA Provider default block size for the specifiedalgorithm
should 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[])
). ThestreamingBlockSize
attribute is used when the block cipher is used for streaming operations. The default value is0
which retains the JCA Provider default.
-
setBlockSize
public void setBlockSize(int blockSize)
Sets the block cipher's block size to be used when constructingCipher
transformation string.0
indicates that the JCA Provider default block size for the specifiedalgorithm
should 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[])
). ThestreamingBlockSize
attribute is used when the block cipher is used for streaming operations. The default value is0
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 specifiedalgorithm
.
-
getStreamingModeName
public String getStreamingModeName()
Same purpose as themodeName
attribute, 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 themodeName
attribute, the default value of this attribute is notnull
- it isCBC
for reasons described in the class-level JavaDoc in theStreaming
section.- Returns:
- the transformation string mode name to be used for streaming operations only.
-
setStreamingModeName
public void setStreamingModeName(String streamingModeName)
Sets the transformation string mode name to be used for streaming operations only. The default value isCBC
for reasons described in the class-level JavaDoc in theStreaming
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 isCBC
for reasons described in the class-level JavaDoc in theStreaming
section.- Parameters:
mode
- the transformation string mode to be used for streaming operations only
-
getStreamingPaddingSchemeName
public String getStreamingPaddingSchemeName()
-
setStreamingPaddingSchemeName
public void setStreamingPaddingSchemeName(String streamingPaddingSchemeName)
-
setStreamingPaddingScheme
public void setStreamingPaddingScheme(PaddingScheme scheme)
-
getStreamingBlockSize
public int getStreamingBlockSize()
-
setStreamingBlockSize
public void setStreamingBlockSize(int streamingBlockSize)
-
getTransformationString
protected String getTransformationString(boolean streaming)
Returns the transformation string to use with theCipher.getInstance(java.lang.String)
call. Ifstreaming
istrue
, 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). Ifstreaming
isfalse
a normal block-cipher transformation string will be constructed and cached for later re-use.- Overrides:
getTransformationString
in 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 configuredmodeName
is compatible with initialization vectors as well as the result of the configuredgenerateInitializationVectors
value.- Overrides:
isGenerateInitializationVectors
in classJcaCipherService
- 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.
-
generateInitializationVector
protected byte[] generateInitializationVector(boolean streaming)
- Overrides:
generateInitializationVector
in classJcaCipherService
-
-