ByteSource decryptInternal(byte[] ciphertext, byte[] key) throws CryptoException {

        byte[] encrypted = ciphertext;

        //No IV, check if we need to read the IV from the stream:
        byte[] iv = null;

        if (isGenerateInitializationVectors(false)) {
            try {
                //We are generating IVs, so the ciphertext argument array is not actually 100% cipher text.  Instead, it
                //is:
                // - the first N bytes is the initialization vector, where N equals the value of the
                // 'initializationVectorSize' attribute.
                // - the remaining bytes in the method argument (arg.length - N) is the real cipher text.

                //So we need to chunk the method argument into its constituent parts to find the IV and then use
                //the IV to decrypt the real ciphertext:

                int ivSize = getInitializationVectorSize();
                int ivByteSize = ivSize / BITS_PER_BYTE;

                //now we know how large the iv is, so extract the iv bytes:
                iv = new byte[ivByteSize];
                System.arraycopy(ciphertext, 0, iv, 0, ivByteSize);

                //remaining data is the actual encrypted ciphertext.  Isolate it:
                int encryptedSize = ciphertext.length - ivByteSize;
                encrypted = new byte[encryptedSize];
                System.arraycopy(ciphertext, ivByteSize, encrypted, 0, encryptedSize);
            } catch (Exception e) {
                String msg = "Unable to correctly extract the Initialization Vector or ciphertext.";
                throw new CryptoException(msg, e);
            }
        }

        return decryptInternal(encrypted, key, iv);
    }
Returns the transformation string to use with the {@link javax.crypto.Cipher#getInstance} invocation when
creating a new {@code Cipher} instance.  This default implementation always returns
{@link #getAlgorithmName() getAlgorithmName()}.  Block cipher implementations will want to override this method
to support appending cipher operation modes and padding schemes.

@param streaming if the transformation string is going to be used for a Cipher for stream-based encryption or not.
@return the transformation string to use with the {@link javax.crypto.Cipher#getInstance} invocation when
creating a new {@code Cipher} instance.
crypto/cipher/src/main/java/org/apache/shiro/crypto/cipher/JcaCipherService.java