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, 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[])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 theblockSizeattribute. 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 theinitializationVectorSizeis usually the same as theblockSizein 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 themodeattribute, which accepts a type-safeOperationModeenum 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 blockCipherServiceinstances to theCBCmode, specifically to support auto-generation of initialization vectors during encryption. This is different than the JDK's defaultECBmode becauseECBdoes not support initialization vectors, which are necessary for strong encryption. See theJcaCipherService parent classclass JavaDoc for an extensive explanation on why we do this and why we do not use the SunECBdefault. You also might also want read the Wikipedia section on ECB and look at the encrypted image to see an example of whyECBshould not be used in security-sensitive environments. In the rare case that you need to override the default with a mode not represented by theOperationModeenum, you may specify the raw mode name string that will be recognized by your JCA provider via themodeNameattribute. Because this is not type-safe, it is recommended only to use this attribute if theOperationModeenum does not represent your desired mode. NOTE: If you change the mode to one that does not support initialization vectors (such asECBorNONE), you must turn off auto-generated initialization vectors by settinggenerateInitializationVectorstofalse. 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 thepaddingSchemeattribute, which accepts a type-safePaddingSchemeenum instance. Like theOperationModeenum, 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.PKCS5scheme, specifically to be compliant with the default behavior of auto-generating initialization vectors during encryption (see theJcaCipherService parent classclass JavaDoc for why). In the rare case that you need to override the default with a scheme not represented by thePaddingSchemeenum, you may specify the raw padding scheme name string that will be recognized by your JCA provider via thepaddingSchemeNameattribute. Because this is not type-safe, it is recommended only to use this attribute if thePaddingSchemeenum 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 modewith astreaming block sizeof 8 bits. This is why theCipherServiceinterface 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, andpaddingSchemeattributes 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 newDefaultBlockCipherServiceusing the specified block cipheralgorithmName.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected byte[]generateInitializationVector(boolean streaming)intgetBlockSize()StringgetModeName()StringgetPaddingSchemeName()intgetStreamingBlockSize()StringgetStreamingModeName()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[])).StringgetStreamingPaddingSchemeName()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)voidsetStreamingMode(OperationMode mode)Sets 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.voidsetStreamingPaddingScheme(PaddingScheme scheme)voidsetStreamingPaddingSchemeName(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 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 Detail
-
getModeName
public String 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
public void setModeName(String modeName)
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.- Parameters:
modeName- the cipher operation mode name to be used when constructingCiphertransformation string, ornullif the JCA Provider default mode for the specifiedalgorithmshould 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 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
public String 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
public void setPaddingSchemeName(String paddingSchemeName)
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.- Parameters:
paddingSchemeName- the padding scheme name to be used when constructingCiphertransformation string, ornullif the JCA Provider default padding scheme for the specifiedalgorithmshould 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 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
public String 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
public void setStreamingModeName(String streamingModeName)
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
public void setStreamingMode(OperationMode mode)
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
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. 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
-
-