Package org.apache.shiro.crypto
Class JcaCipherService
- java.lang.Object
-
- org.apache.shiro.crypto.JcaCipherService
-
- All Implemented Interfaces:
CipherService
- Direct Known Subclasses:
AbstractSymmetricCipherService
public abstract class JcaCipherService extends Object implements CipherService
AbstractCipherServiceimplementation utilizing Java's JCA APIs.Auto-generated Initialization Vectors
Shiro does something by default for all of itsCipherServiceimplementations that the JCACipherdoes not do: by default, initialization vectors are automatically randomly generated and prepended to encrypted data before returning from theencryptmethods. That is, the returned byte array orOutputStreamis actually a concatenation of an initialization vector byte array plus the actual encrypted data byte array. Thedecryptmethods 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 callencryptmultiple 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 thegenerateInitializationVectorsproperty tofalse, 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 theinitializationVectorSizeattribute to128bits, 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 thatinitializationVectorSizevalues 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 of8to ensure that the IV can be correctly represented as a byte array (thesetInitializationVectorSizemutator method enforces this).- Since:
- 1.0
-
-
Constructor Summary
Constructors Modifier Constructor Description protectedJcaCipherService(String algorithmName)Creates a newJcaCipherServiceinstance which will use the specified cipheralgorithmNamefor all encryption, decryption, and key operations.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected AlgorithmParameterSpeccreateParameterSpec(byte[] iv, boolean streaming)org.apache.shiro.util.ByteSourcedecrypt(byte[] ciphertext, byte[] key)Decrypts encrypted data via the specified cipher key and returns the original (pre-encrypted) data.voiddecrypt(InputStream in, OutputStream out, byte[] key)Receives encrypted data from the givenInputStream, decrypts it, and sends the resulting decrypted data to the givenOutputStream.org.apache.shiro.util.ByteSourceencrypt(byte[] plaintext, byte[] key)Encrypts data via the specified cipher key.voidencrypt(InputStream in, OutputStream out, byte[] key)Receives the data from the givenInputStream, encrypts it, and sends the resulting encrypted data to the givenOutputStream.protected SecureRandomensureSecureRandom()protected byte[]generateInitializationVector(boolean streaming)StringgetAlgorithmName()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 SecureRandomgetDefaultSecureRandom()intgetInitializationVectorSize()Returns the algorithm-specific size in bits of generated initialization vectors.intgetKeySize()Returns the size in bits (not bytes) of generated cipher keys.SecureRandomgetSecureRandom()Returns a source of randomness for encryption operations.intgetStreamingBufferSize()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[])anddecrypt(java.io.InputStream, java.io.OutputStream, byte[])).protected StringgetTransformationString(boolean streaming)Returns the transformation string to use with theCipher.getInstance(java.lang.String)invocation when creating a newCipherinstance.booleanisGenerateInitializationVectors()protected booleanisGenerateInitializationVectors(boolean streaming)voidsetGenerateInitializationVectors(boolean generateInitializationVectors)voidsetInitializationVectorSize(int initializationVectorSize)Sets the algorithm-specific initialization vector size in bits (not bytes!) to be used when generating initialization vectors.voidsetKeySize(int keySize)Sets the size in bits (not bytes) of generated cipher keys.voidsetSecureRandom(SecureRandom secureRandom)Sets a source of randomness for encryption operations.voidsetStreamingBufferSize(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[])anddecrypt(java.io.InputStream, java.io.OutputStream, byte[])).
-
-
-
Constructor Detail
-
JcaCipherService
protected JcaCipherService(String algorithmName)
Creates a newJcaCipherServiceinstance which will use the specified cipheralgorithmNamefor all encryption, decryption, and key operations. Also, the following defaults are set:keySize= 128 bitsinitializationVectorSize= 128 bitsstreamingBufferSize= 512 bytes
- 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 IllegalArgumentExceptionSets the algorithm-specific initialization vector size in bits (not bytes!) to be used when generating initialization vectors. The value must be a multiple of8to 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 of8.
-
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[])anddecrypt(java.io.InputStream, java.io.OutputStream, byte[])). Default size is512bytes.- 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[])anddecrypt(java.io.InputStream, java.io.OutputStream, byte[])). Default size is512bytes.- 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 JDKSHA1PRNGinstance 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
SHA1PRNGinstance 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 JDKSHA1PRNGinstance 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 JDKSHA1PRNGinstance 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 theCipher.getInstance(java.lang.String)invocation when creating a newCipherinstance. This default implementation always returnsgetAlgorithmName(). 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 newCipherinstance.
-
generateInitializationVector
protected byte[] generateInitializationVector(boolean streaming)
-
encrypt
public org.apache.shiro.util.ByteSource encrypt(byte[] plaintext, byte[] key)Description copied from interface:CipherServiceEncrypts data via the specified cipher key. Note that the key must be in a format understood by theCipherServiceimplementation.- Specified by:
encryptin interfaceCipherService- Parameters:
plaintext- the data to encryptkey- the cipher key used during encryption.- Returns:
- a byte source with the encrypted representation of the specified raw data.
-
decrypt
public org.apache.shiro.util.ByteSource decrypt(byte[] ciphertext, byte[] key) throws org.apache.shiro.crypto.CryptoExceptionDescription copied from interface:CipherServiceDecrypts 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:
decryptin interfaceCipherService- Parameters:
ciphertext- the previously encrypted data to decryptkey- the cipher key used during decryption.- Returns:
- a byte source representing the original form of the specified encrypted data.
- Throws:
org.apache.shiro.crypto.CryptoException- if there is an error during decryption
-
encrypt
public void encrypt(InputStream in, OutputStream out, byte[] key) throws org.apache.shiro.crypto.CryptoException
Description copied from interface:CipherServiceReceives the data from the givenInputStream, encrypts it, and sends the resulting encrypted data to the givenOutputStream. 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:
encryptin interfaceCipherService- Parameters:
in- the stream supplying the data to encryptout- the stream to send the encrypted datakey- the cipher key to use for encryption- Throws:
org.apache.shiro.crypto.CryptoException- if there is any problem during encryption.
-
decrypt
public void decrypt(InputStream in, OutputStream out, byte[] key) throws org.apache.shiro.crypto.CryptoException
Description copied from interface:CipherServiceReceives encrypted data from the givenInputStream, decrypts it, and sends the resulting decrypted data to the givenOutputStream. 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:
decryptin interfaceCipherService- Parameters:
in- the stream supplying the data to decryptout- the stream to send the decrypted datakey- the cipher key to use for decryption- Throws:
org.apache.shiro.crypto.CryptoException- if there is any problem during decryption.
-
createParameterSpec
protected AlgorithmParameterSpec createParameterSpec(byte[] iv, boolean streaming)
-
-