protected byte[] generateInitializationVector(boolean streaming) {
        int size = getInitializationVectorSize();
        if (size <= 0) {
            String msg = "initializationVectorSize property must be greater than zero.  This number is "
                    + "typically set in the " + CipherService.class.getSimpleName() + " subclass constructor.  "
                    + "Also check your configuration to ensure that if you are setting a value, it is positive.";
            throw new IllegalStateException(msg);
        }
        if (size % BITS_PER_BYTE != 0) {
            String msg = "initializationVectorSize property must be a multiple of 8 to represent as a byte array.";
            throw new IllegalStateException(msg);
        }
        int sizeInBytes = size / BITS_PER_BYTE;
        byte[] ivBytes = new byte[sizeInBytes];
        SecureRandom random = ensureSecureRandom();
        random.nextBytes(ivBytes);
        return ivBytes;
    }
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