Abstract {@code CipherService} implementation utilizing Java's JCA APIs. <h2>Auto-generated Initialization Vectors</h2> Shiro does something by default for all of its {@code CipherService} implementations that the JCA {@link javax.crypto.Cipher Cipher} does not do: by default, <a href="http://en.wikipedia.org/wiki/Initialization_vector">initialization vector</a>s are automatically randomly generated and prepended to encrypted data before returning from the {@code encrypt} methods. That is, the returned byte array or {@code OutputStream} is actually a concatenation of an initialization vector byte array plus the actual encrypted data byte array. The {@code decrypt} methods in turn know to read this prepended initialization vector before decrypting the real data that follows. <p/> This is highly desirable because initialization vectors guarantee that, for a key and any plaintext, the encrypted output will always be different <em>even if you call {@code encrypt} multiple times with the exact same arguments</em>. This is essential in cryptography to ensure that data patterns cannot be identified across multiple input sources that are the same or similar. <p/> You can turn off this behavior by setting the {@link #setGenerateInitializationVectors(bool) generateInitializationVectors} property to {@code false}, 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. <h3>Initialization Vector Size</h3> This implementation defaults the {@link #setInitializationVectorSize(int) initializationVectorSize} attribute to {@code 128} bits, 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. <p/> Also note that {@code initializationVectorSize} values 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 of {@code 8} to ensure that the IV can be correctly represented as a byte array (the {@link #setInitializationVectorSize(int) setInitializationVectorSize} mutator method enforces this).