blob: 576ed7302e8fb1e0d8a036ef0df03d51e13acf4d [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Source code</title>
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">
</head>
<body>
<main role="main">
<div class="sourceContainer">
<pre><span class="sourceLineNo">001</span><a id="line.1">/*</a>
<span class="sourceLineNo">002</span><a id="line.2"> * Licensed to the Apache Software Foundation (ASF) under one</a>
<span class="sourceLineNo">003</span><a id="line.3"> * or more contributor license agreements. See the NOTICE file</a>
<span class="sourceLineNo">004</span><a id="line.4"> * distributed with this work for additional information</a>
<span class="sourceLineNo">005</span><a id="line.5"> * regarding copyright ownership. The ASF licenses this file</a>
<span class="sourceLineNo">006</span><a id="line.6"> * to you under the Apache License, Version 2.0 (the</a>
<span class="sourceLineNo">007</span><a id="line.7"> * "License"); you may not use this file except in compliance</a>
<span class="sourceLineNo">008</span><a id="line.8"> * with the License. You may obtain a copy of the License at</a>
<span class="sourceLineNo">009</span><a id="line.9"> *</a>
<span class="sourceLineNo">010</span><a id="line.10"> * http://www.apache.org/licenses/LICENSE-2.0</a>
<span class="sourceLineNo">011</span><a id="line.11"> *</a>
<span class="sourceLineNo">012</span><a id="line.12"> * Unless required by applicable law or agreed to in writing,</a>
<span class="sourceLineNo">013</span><a id="line.13"> * software distributed under the License is distributed on an</a>
<span class="sourceLineNo">014</span><a id="line.14"> * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</a>
<span class="sourceLineNo">015</span><a id="line.15"> * KIND, either express or implied. See the License for the</a>
<span class="sourceLineNo">016</span><a id="line.16"> * specific language governing permissions and limitations</a>
<span class="sourceLineNo">017</span><a id="line.17"> * under the License.</a>
<span class="sourceLineNo">018</span><a id="line.18"> */</a>
<span class="sourceLineNo">019</span><a id="line.19">package org.apache.shiro.crypto;</a>
<span class="sourceLineNo">020</span><a id="line.20"></a>
<span class="sourceLineNo">021</span><a id="line.21">import org.apache.shiro.util.StringUtils;</a>
<span class="sourceLineNo">022</span><a id="line.22"></a>
<span class="sourceLineNo">023</span><a id="line.23">/**</a>
<span class="sourceLineNo">024</span><a id="line.24"> * Base abstract class for block cipher algorithms.</a>
<span class="sourceLineNo">025</span><a id="line.25"> *</a>
<span class="sourceLineNo">026</span><a id="line.26"> * &lt;h2&gt;Usage&lt;/h2&gt;</a>
<span class="sourceLineNo">027</span><a id="line.27"> * Note that this class exists mostly to simplify algorithm-specific subclasses. Unless you understand the concepts of</a>
<span class="sourceLineNo">028</span><a id="line.28"> * cipher modes of operation, block sizes, and padding schemes, and you want direct control of these things, you should</a>
<span class="sourceLineNo">029</span><a id="line.29"> * typically not uses instances of this class directly. Instead, algorithm-specific subclasses, such as</a>
<span class="sourceLineNo">030</span><a id="line.30"> * {@link AesCipherService}, {@link BlowfishCipherService}, and others are usually better suited for regular use.</a>
<span class="sourceLineNo">031</span><a id="line.31"> * &lt;p/&gt;</a>
<span class="sourceLineNo">032</span><a id="line.32"> * However, if you have the need to create a custom block cipher service where no sufficient algorithm-specific subclass</a>
<span class="sourceLineNo">033</span><a id="line.33"> * exists in Shiro, this class would be very useful.</a>
<span class="sourceLineNo">034</span><a id="line.34"> *</a>
<span class="sourceLineNo">035</span><a id="line.35"> * &lt;h2&gt;Configuration&lt;/h2&gt;</a>
<span class="sourceLineNo">036</span><a id="line.36"> * Block ciphers can accept configuration parameters that direct how they operate. These parameters concatenated</a>
<span class="sourceLineNo">037</span><a id="line.37"> * together in a single String comprise what the JDK JCA documentation calls a</a>
<span class="sourceLineNo">038</span><a id="line.38"> * &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#trans"&gt;transformation</a>
<span class="sourceLineNo">039</span><a id="line.39"> * string&lt;/a&gt;. We think that it is better for Shiro to construct this transformation string automatically based on its</a>
<span class="sourceLineNo">040</span><a id="line.40"> * constituent parts instead of having the end-user construct the string manually, which may be error prone or</a>
<span class="sourceLineNo">041</span><a id="line.41"> * confusing. To that end, Shiro {@link DefaultBlockCipherService}s have attributes that can be set individually in</a>
<span class="sourceLineNo">042</span><a id="line.42"> * a type-safe manner based on your configuration needs, and Shiro will build the transformation string for you.</a>
<span class="sourceLineNo">043</span><a id="line.43"> * &lt;p/&gt;</a>
<span class="sourceLineNo">044</span><a id="line.44"> * The following sections typically document the configuration options for block (byte array)</a>
<span class="sourceLineNo">045</span><a id="line.45"> * {@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])} method invocations. Streaming configuration</a>
<span class="sourceLineNo">046</span><a id="line.46"> * for those same attributes are done via mirrored {@code streaming}* attributes, and their purpose is identical, but</a>
<span class="sourceLineNo">047</span><a id="line.47"> * they're only used during streaming {@link #encrypt(java.io.InputStream, java.io.OutputStream, byte[])} and</a>
<span class="sourceLineNo">048</span><a id="line.48"> * {@link #decrypt(java.io.InputStream, java.io.OutputStream, byte[])} methods. See the &amp;quot;Streaming&amp;quot;</a>
<span class="sourceLineNo">049</span><a id="line.49"> * section below for more.</a>
<span class="sourceLineNo">050</span><a id="line.50"> *</a>
<span class="sourceLineNo">051</span><a id="line.51"> * &lt;h3&gt;Block Size&lt;/h3&gt;</a>
<span class="sourceLineNo">052</span><a id="line.52"> * The block size specifies the number of bits (not bytes) that the cipher operates on when performing an operation.</a>
<span class="sourceLineNo">053</span><a id="line.53"> * It can be specified explicitly via the {@link #setBlockSize blockSize} attribute. If not set, the JCA Provider</a>
<span class="sourceLineNo">054</span><a id="line.54"> * default will be used based on the cipher algorithm. Block sizes are usually very algorithm specific, so set this</a>
<span class="sourceLineNo">055</span><a id="line.55"> * value only if you know you don't want the JCA Provider's default for the desired algorithm. For example, the</a>
<span class="sourceLineNo">056</span><a id="line.56"> * AES algorithm's Rijndael implementation &lt;em&gt;only&lt;/em&gt; supports a 128 bit block size and will not work with any other</a>
<span class="sourceLineNo">057</span><a id="line.57"> * size.</a>
<span class="sourceLineNo">058</span><a id="line.58"> * &lt;p/&gt;</a>
<span class="sourceLineNo">059</span><a id="line.59"> * Also note that the {@link #setInitializationVectorSize initializationVectorSize} is usually the same as the</a>
<span class="sourceLineNo">060</span><a id="line.60"> * {@link #setBlockSize blockSize} in block ciphers. If you change either attribute, you should ensure that the other</a>
<span class="sourceLineNo">061</span><a id="line.61"> * attribute is correct for the target cipher algorithm.</a>
<span class="sourceLineNo">062</span><a id="line.62"> *</a>
<span class="sourceLineNo">063</span><a id="line.63"> * &lt;h3&gt;Operation Mode&lt;/h3&gt;</a>
<span class="sourceLineNo">064</span><a id="line.64"> * You may set the block cipher's&lt;a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation"&gt;mode of</a>
<span class="sourceLineNo">065</span><a id="line.65"> * operation&lt;/a&gt; via the {@link #setMode(OperationMode) mode} attribute, which accepts a type-safe</a>
<span class="sourceLineNo">066</span><a id="line.66"> * {@link OperationMode OperationMode} enum instance. This type safety helps avoid typos when specifying the mode and</a>
<span class="sourceLineNo">067</span><a id="line.67"> * guarantees that the mode name will be recognized by the underlying JCA Provider.</a>
<span class="sourceLineNo">068</span><a id="line.68"> * &lt;p/&gt;</a>
<span class="sourceLineNo">069</span><a id="line.69"> * &lt;b&gt;*&lt;/b&gt;If no operation mode is specified, Shiro defaults all of its block {@code CipherService} instances to the</a>
<span class="sourceLineNo">070</span><a id="line.70"> * {@link OperationMode#CBC CBC} mode, specifically to support auto-generation of initialization vectors during</a>
<span class="sourceLineNo">071</span><a id="line.71"> * encryption. This is different than the JDK's default {@link OperationMode#ECB ECB} mode because {@code ECB} does</a>
<span class="sourceLineNo">072</span><a id="line.72"> * not support initialization vectors, which are necessary for strong encryption. See the</a>
<span class="sourceLineNo">073</span><a id="line.73"> * {@link org.apache.shiro.crypto.JcaCipherService JcaCipherService parent class} class JavaDoc for an extensive</a>
<span class="sourceLineNo">074</span><a id="line.74"> * explanation on why we do this and why we do not use the Sun {@code ECB} default. You also might also want read</a>
<span class="sourceLineNo">075</span><a id="line.75"> * the &lt;a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29"&gt;Wikipedia</a>
<span class="sourceLineNo">076</span><a id="line.76"> * section on ECB&lt;a/&gt; and look at the encrypted image to see an example of why {@code ECB} should not be used in</a>
<span class="sourceLineNo">077</span><a id="line.77"> * security-sensitive environments.</a>
<span class="sourceLineNo">078</span><a id="line.78"> * &lt;p/&gt;</a>
<span class="sourceLineNo">079</span><a id="line.79"> * In the rare case that you need to override the default with a mode not represented</a>
<span class="sourceLineNo">080</span><a id="line.80"> * by the {@link OperationMode} enum, you may specify the raw mode name string that will be recognized by your JCA</a>
<span class="sourceLineNo">081</span><a id="line.81"> * provider via the {@link #setModeName modeName} attribute. Because this is not type-safe, it is recommended only to</a>
<span class="sourceLineNo">082</span><a id="line.82"> * use this attribute if the {@link OperationMode} enum does not represent your desired mode.</a>
<span class="sourceLineNo">083</span><a id="line.83"> * &lt;p/&gt;</a>
<span class="sourceLineNo">084</span><a id="line.84"> * &lt;b&gt;NOTE:&lt;/b&gt; If you change the mode to one that does not support initialization vectors (such as</a>
<span class="sourceLineNo">085</span><a id="line.85"> * {@link OperationMode#ECB ECB} or {@link OperationMode#NONE NONE}), you &lt;em&gt;must&lt;/em&gt; turn off auto-generated</a>
<span class="sourceLineNo">086</span><a id="line.86"> * initialization vectors by setting {@link #setGenerateInitializationVectors(boolean) generateInitializationVectors}</a>
<span class="sourceLineNo">087</span><a id="line.87"> * to {@code false}. Abandoning initialization vectors significantly weakens encryption, so think twice before</a>
<span class="sourceLineNo">088</span><a id="line.88"> * disabling this feature.</a>
<span class="sourceLineNo">089</span><a id="line.89"> *</a>
<span class="sourceLineNo">090</span><a id="line.90"> * &lt;h3&gt;Padding Scheme&lt;/h3&gt;</a>
<span class="sourceLineNo">091</span><a id="line.91"> * Because block ciphers process messages in fixed-length blocks, if the final block in a message is not equal to the</a>
<span class="sourceLineNo">092</span><a id="line.92"> * block length, &lt;a href="http://en.wikipedia.org/wiki/Padding_(cryptography)"&gt;padding&lt;/a&gt; is applied to match that</a>
<span class="sourceLineNo">093</span><a id="line.93"> * size to maintain the total length of the message. This is good because it protects data patterns from being</a>
<span class="sourceLineNo">094</span><a id="line.94"> * identified - when all chunks look the same length, it is much harder to infer what that data might be.</a>
<span class="sourceLineNo">095</span><a id="line.95"> * &lt;p/&gt;</a>
<span class="sourceLineNo">096</span><a id="line.96"> * You may set a padding scheme via the {@link #setPaddingScheme(PaddingScheme) paddingScheme} attribute, which</a>
<span class="sourceLineNo">097</span><a id="line.97"> * accepts a type-safe {@link PaddingScheme PaddingScheme} enum instance. Like the {@link OperationMode} enum,</a>
<span class="sourceLineNo">098</span><a id="line.98"> * this enum offers type safety to help avoid typos and guarantees that the mode will be recongized by the underlying</a>
<span class="sourceLineNo">099</span><a id="line.99"> * JCA provider.</a>
<span class="sourceLineNo">100</span><a id="line.100"> * &lt;p/&gt;</a>
<span class="sourceLineNo">101</span><a id="line.101"> * &lt;b&gt;*&lt;/b&gt;If no padding scheme is specified, this class defaults to the {@link PaddingScheme#PKCS5} scheme, specifically</a>
<span class="sourceLineNo">102</span><a id="line.102"> * to be compliant with the default behavior of auto-generating initialization vectors during encryption (see the</a>
<span class="sourceLineNo">103</span><a id="line.103"> * {@link org.apache.shiro.crypto.JcaCipherService JcaCipherService parent class} class JavaDoc for why).</a>
<span class="sourceLineNo">104</span><a id="line.104"> * &lt;p/&gt;</a>
<span class="sourceLineNo">105</span><a id="line.105"> * In the rare case that you need to override the default with a scheme not represented by the {@link PaddingScheme}</a>
<span class="sourceLineNo">106</span><a id="line.106"> * enum, you may specify the raw padding scheme name string that will be recognized by your JCA provider via the</a>
<span class="sourceLineNo">107</span><a id="line.107"> * {@link #setPaddingScheme paddingSchemeName} attribute. Because this is not type-safe, it is recommended only to</a>
<span class="sourceLineNo">108</span><a id="line.108"> * use this attribute if the {@link PaddingScheme} enum does not represent your desired scheme.</a>
<span class="sourceLineNo">109</span><a id="line.109"> *</a>
<span class="sourceLineNo">110</span><a id="line.110"> * &lt;h2&gt;Streaming&lt;/h2&gt;</a>
<span class="sourceLineNo">111</span><a id="line.111"> * Most people don't think of using block ciphers as stream ciphers, since their name implies working</a>
<span class="sourceLineNo">112</span><a id="line.112"> * with block data (i.e. byte arrays) only. However, block ciphers can be turned into byte-oriented stream ciphers by</a>
<span class="sourceLineNo">113</span><a id="line.113"> * using an appropriate {@link OperationMode operation mode} with a {@link #getStreamingBlockSize() streaming block size}</a>
<span class="sourceLineNo">114</span><a id="line.114"> * of 8 bits. This is why the {@link CipherService} interface provides both block and streaming operations.</a>
<span class="sourceLineNo">115</span><a id="line.115"> * &lt;p/&gt;</a>
<span class="sourceLineNo">116</span><a id="line.116"> * Because this streaming 8-bit block size rarely changes across block-cipher algorithms, default values have been set</a>
<span class="sourceLineNo">117</span><a id="line.117"> * for all three streaming configuration parameters. The defaults are:</a>
<span class="sourceLineNo">118</span><a id="line.118"> * &lt;ul&gt;</a>
<span class="sourceLineNo">119</span><a id="line.119"> * &lt;li&gt;{@link #setStreamingBlockSize(int) streamingBlockSize} = {@code 8} (bits)&lt;/li&gt;</a>
<span class="sourceLineNo">120</span><a id="line.120"> * &lt;li&gt;{@link #setStreamingMode streamingMode} = {@link OperationMode#CBC CBC}&lt;/li&gt;</a>
<span class="sourceLineNo">121</span><a id="line.121"> * &lt;li&gt;{@link #setStreamingPaddingScheme(PaddingScheme) streamingPaddingScheme} = {@link PaddingScheme#PKCS5 PKCS5}&lt;/li&gt;</a>
<span class="sourceLineNo">122</span><a id="line.122"> * &lt;/ul&gt;</a>
<span class="sourceLineNo">123</span><a id="line.123"> * &lt;p/&gt;</a>
<span class="sourceLineNo">124</span><a id="line.124"> * These attributes have the same meaning as the {@code mode}, {@code blockSize}, and {@code paddingScheme} attributes</a>
<span class="sourceLineNo">125</span><a id="line.125"> * described above, but they are applied during streaming method invocations only ({@link #encrypt(java.io.InputStream, java.io.OutputStream, byte[])}</a>
<span class="sourceLineNo">126</span><a id="line.126"> * and {@link #decrypt(java.io.InputStream, java.io.OutputStream, byte[])}).</a>
<span class="sourceLineNo">127</span><a id="line.127"> *</a>
<span class="sourceLineNo">128</span><a id="line.128"> * @see BlowfishCipherService</a>
<span class="sourceLineNo">129</span><a id="line.129"> * @see AesCipherService</a>
<span class="sourceLineNo">130</span><a id="line.130"> * @see &lt;a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation"&gt;Wikipedia: Block Cipher Modes of Operation&lt;/a&gt;</a>
<span class="sourceLineNo">131</span><a id="line.131"> * @since 1.0</a>
<span class="sourceLineNo">132</span><a id="line.132"> */</a>
<span class="sourceLineNo">133</span><a id="line.133">public class DefaultBlockCipherService extends AbstractSymmetricCipherService {</a>
<span class="sourceLineNo">134</span><a id="line.134"></a>
<span class="sourceLineNo">135</span><a id="line.135"> private static final int DEFAULT_BLOCK_SIZE = 0;</a>
<span class="sourceLineNo">136</span><a id="line.136"></a>
<span class="sourceLineNo">137</span><a id="line.137"> private static final String TRANSFORMATION_STRING_DELIMITER = "/";</a>
<span class="sourceLineNo">138</span><a id="line.138"> private static final int DEFAULT_STREAMING_BLOCK_SIZE = 8; //8 bits (1 byte)</a>
<span class="sourceLineNo">139</span><a id="line.139"></a>
<span class="sourceLineNo">140</span><a id="line.140"> private String modeName;</a>
<span class="sourceLineNo">141</span><a id="line.141"> private int blockSize; //size in bits (not bytes) - i.e. a blockSize of 8 equals 1 byte. negative or zero value = use system default</a>
<span class="sourceLineNo">142</span><a id="line.142"> private String paddingSchemeName;</a>
<span class="sourceLineNo">143</span><a id="line.143"></a>
<span class="sourceLineNo">144</span><a id="line.144"> private String streamingModeName;</a>
<span class="sourceLineNo">145</span><a id="line.145"> private int streamingBlockSize;</a>
<span class="sourceLineNo">146</span><a id="line.146"> private String streamingPaddingSchemeName;</a>
<span class="sourceLineNo">147</span><a id="line.147"></a>
<span class="sourceLineNo">148</span><a id="line.148"> private String transformationString; //cached value - rebuilt whenever any of its constituent parts change</a>
<span class="sourceLineNo">149</span><a id="line.149"> private String streamingTransformationString; //cached value - rebuilt whenever any of its constituent parts change</a>
<span class="sourceLineNo">150</span><a id="line.150"></a>
<span class="sourceLineNo">151</span><a id="line.151"></a>
<span class="sourceLineNo">152</span><a id="line.152"> /**</a>
<span class="sourceLineNo">153</span><a id="line.153"> * Creates a new {@link DefaultBlockCipherService} using the specified block cipher {@code algorithmName}. Per this</a>
<span class="sourceLineNo">154</span><a id="line.154"> * class's JavaDoc, this constructor also sets the following defaults:</a>
<span class="sourceLineNo">155</span><a id="line.155"> * &lt;ul&gt;</a>
<span class="sourceLineNo">156</span><a id="line.156"> * &lt;li&gt;{@code streamingMode} = {@link OperationMode#CBC CBC}&lt;/li&gt;</a>
<span class="sourceLineNo">157</span><a id="line.157"> * &lt;li&gt;{@code streamingPaddingScheme} = {@link PaddingScheme#NONE none}&lt;/li&gt;</a>
<span class="sourceLineNo">158</span><a id="line.158"> * &lt;li&gt;{@code streamingBlockSize} = 8&lt;/li&gt;</a>
<span class="sourceLineNo">159</span><a id="line.159"> * &lt;/ul&gt;</a>
<span class="sourceLineNo">160</span><a id="line.160"> * All other attributes are null/unset, indicating the JCA Provider defaults will be used.</a>
<span class="sourceLineNo">161</span><a id="line.161"> *</a>
<span class="sourceLineNo">162</span><a id="line.162"> * @param algorithmName the block cipher algorithm to use when encrypting and decrypting</a>
<span class="sourceLineNo">163</span><a id="line.163"> */</a>
<span class="sourceLineNo">164</span><a id="line.164"> public DefaultBlockCipherService(String algorithmName) {</a>
<span class="sourceLineNo">165</span><a id="line.165"> super(algorithmName);</a>
<span class="sourceLineNo">166</span><a id="line.166"></a>
<span class="sourceLineNo">167</span><a id="line.167"> this.modeName = OperationMode.CBC.name();</a>
<span class="sourceLineNo">168</span><a id="line.168"> this.paddingSchemeName = PaddingScheme.PKCS5.getTransformationName();</a>
<span class="sourceLineNo">169</span><a id="line.169"> this.blockSize = DEFAULT_BLOCK_SIZE; //0 = use the JCA provider's default</a>
<span class="sourceLineNo">170</span><a id="line.170"></a>
<span class="sourceLineNo">171</span><a id="line.171"> this.streamingModeName = OperationMode.CBC.name();</a>
<span class="sourceLineNo">172</span><a id="line.172"> this.streamingPaddingSchemeName = PaddingScheme.PKCS5.getTransformationName();</a>
<span class="sourceLineNo">173</span><a id="line.173"> this.streamingBlockSize = DEFAULT_STREAMING_BLOCK_SIZE;</a>
<span class="sourceLineNo">174</span><a id="line.174"> }</a>
<span class="sourceLineNo">175</span><a id="line.175"></a>
<span class="sourceLineNo">176</span><a id="line.176"> /**</a>
<span class="sourceLineNo">177</span><a id="line.177"> * Returns the cipher operation mode name (as a String) to be used when constructing</a>
<span class="sourceLineNo">178</span><a id="line.178"> * {@link javax.crypto.Cipher Cipher} transformation string or {@code null} if the JCA Provider default mode for</a>
<span class="sourceLineNo">179</span><a id="line.179"> * the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">180</span><a id="line.180"> * &lt;p/&gt;</a>
<span class="sourceLineNo">181</span><a id="line.181"> * This attribute is used &lt;em&gt;only&lt;/em&gt; when constructing the transformation string for block (byte array)</a>
<span class="sourceLineNo">182</span><a id="line.182"> * operations ({@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])}). The</a>
<span class="sourceLineNo">183</span><a id="line.183"> * {@link #getStreamingModeName() streamingModeName} attribute is used when the block cipher is used for</a>
<span class="sourceLineNo">184</span><a id="line.184"> * streaming operations.</a>
<span class="sourceLineNo">185</span><a id="line.185"> * &lt;p/&gt;</a>
<span class="sourceLineNo">186</span><a id="line.186"> * The default value is {@code null} to retain the JCA Provider default.</a>
<span class="sourceLineNo">187</span><a id="line.187"> *</a>
<span class="sourceLineNo">188</span><a id="line.188"> * @return the cipher operation mode name (as a String) to be used when constructing the</a>
<span class="sourceLineNo">189</span><a id="line.189"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code null} if the JCA Provider default</a>
<span class="sourceLineNo">190</span><a id="line.190"> * mode for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">191</span><a id="line.191"> */</a>
<span class="sourceLineNo">192</span><a id="line.192"> public String getModeName() {</a>
<span class="sourceLineNo">193</span><a id="line.193"> return modeName;</a>
<span class="sourceLineNo">194</span><a id="line.194"> }</a>
<span class="sourceLineNo">195</span><a id="line.195"></a>
<span class="sourceLineNo">196</span><a id="line.196"> /**</a>
<span class="sourceLineNo">197</span><a id="line.197"> * Sets the cipher operation mode name to be used when constructing the</a>
<span class="sourceLineNo">198</span><a id="line.198"> * {@link javax.crypto.Cipher Cipher} transformation string. A {@code null} value indicates that the JCA Provider</a>
<span class="sourceLineNo">199</span><a id="line.199"> * default mode for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">200</span><a id="line.200"> * &lt;p/&gt;</a>
<span class="sourceLineNo">201</span><a id="line.201"> * This attribute is used &lt;em&gt;only&lt;/em&gt; when constructing the transformation string for block (byte array)</a>
<span class="sourceLineNo">202</span><a id="line.202"> * operations ({@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])}). The</a>
<span class="sourceLineNo">203</span><a id="line.203"> * {@link #getStreamingModeName() streamingModeName} attribute is used when the block cipher is used for</a>
<span class="sourceLineNo">204</span><a id="line.204"> * streaming operations.</a>
<span class="sourceLineNo">205</span><a id="line.205"> * &lt;p/&gt;</a>
<span class="sourceLineNo">206</span><a id="line.206"> * The default value is {@code null} to retain the JCA Provider default.</a>
<span class="sourceLineNo">207</span><a id="line.207"> * &lt;p/&gt;</a>
<span class="sourceLineNo">208</span><a id="line.208"> * &lt;b&gt;NOTE:&lt;/b&gt; most standard mode names are represented by the {@link OperationMode OperationMode} enum. That enum</a>
<span class="sourceLineNo">209</span><a id="line.209"> * should be used with the {@link #setMode mode} attribute when possible to retain type-safety and reduce the</a>
<span class="sourceLineNo">210</span><a id="line.210"> * possibility of errors. This method is better used if the {@link OperationMode} enum does not represent the</a>
<span class="sourceLineNo">211</span><a id="line.211"> * necessary mode.</a>
<span class="sourceLineNo">212</span><a id="line.212"> *</a>
<span class="sourceLineNo">213</span><a id="line.213"> * @param modeName the cipher operation mode name to be used when constructing</a>
<span class="sourceLineNo">214</span><a id="line.214"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code null} if the JCA Provider</a>
<span class="sourceLineNo">215</span><a id="line.215"> * default mode for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">216</span><a id="line.216"> * @see #setMode</a>
<span class="sourceLineNo">217</span><a id="line.217"> */</a>
<span class="sourceLineNo">218</span><a id="line.218"> public void setModeName(String modeName) {</a>
<span class="sourceLineNo">219</span><a id="line.219"> this.modeName = modeName;</a>
<span class="sourceLineNo">220</span><a id="line.220"> //clear out the transformation string so the next invocation will rebuild it with the new mode:</a>
<span class="sourceLineNo">221</span><a id="line.221"> this.transformationString = null;</a>
<span class="sourceLineNo">222</span><a id="line.222"> }</a>
<span class="sourceLineNo">223</span><a id="line.223"></a>
<span class="sourceLineNo">224</span><a id="line.224"> /**</a>
<span class="sourceLineNo">225</span><a id="line.225"> * Sets the cipher operation mode of operation to be used when constructing the</a>
<span class="sourceLineNo">226</span><a id="line.226"> * {@link javax.crypto.Cipher Cipher} transformation string. A {@code null} value indicates that the JCA Provider</a>
<span class="sourceLineNo">227</span><a id="line.227"> * default mode for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">228</span><a id="line.228"> * &lt;p/&gt;</a>
<span class="sourceLineNo">229</span><a id="line.229"> * This attribute is used &lt;em&gt;only&lt;/em&gt; when constructing the transformation string for block (byte array)</a>
<span class="sourceLineNo">230</span><a id="line.230"> * operations ({@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])}). The</a>
<span class="sourceLineNo">231</span><a id="line.231"> * {@link #setStreamingMode streamingMode} attribute is used when the block cipher is used for</a>
<span class="sourceLineNo">232</span><a id="line.232"> * streaming operations.</a>
<span class="sourceLineNo">233</span><a id="line.233"> * &lt;p/&gt;</a>
<span class="sourceLineNo">234</span><a id="line.234"> * If the {@link OperationMode} enum cannot represent your desired mode, you can set the name explicitly</a>
<span class="sourceLineNo">235</span><a id="line.235"> * via the {@link #setModeName modeName} attribute directly. However, because {@link OperationMode} represents all</a>
<span class="sourceLineNo">236</span><a id="line.236"> * standard JDK mode names already, ensure that your underlying JCA Provider supports the non-standard name first.</a>
<span class="sourceLineNo">237</span><a id="line.237"> *</a>
<span class="sourceLineNo">238</span><a id="line.238"> * @param mode the cipher operation mode to be used when constructing</a>
<span class="sourceLineNo">239</span><a id="line.239"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code null} if the JCA Provider</a>
<span class="sourceLineNo">240</span><a id="line.240"> * default mode for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">241</span><a id="line.241"> */</a>
<span class="sourceLineNo">242</span><a id="line.242"> public void setMode(OperationMode mode) {</a>
<span class="sourceLineNo">243</span><a id="line.243"> setModeName(mode.name());</a>
<span class="sourceLineNo">244</span><a id="line.244"> }</a>
<span class="sourceLineNo">245</span><a id="line.245"></a>
<span class="sourceLineNo">246</span><a id="line.246"> /**</a>
<span class="sourceLineNo">247</span><a id="line.247"> * Returns the cipher algorithm padding scheme name (as a String) to be used when constructing</a>
<span class="sourceLineNo">248</span><a id="line.248"> * {@link javax.crypto.Cipher Cipher} transformation string or {@code null} if the JCA Provider default mode for</a>
<span class="sourceLineNo">249</span><a id="line.249"> * the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">250</span><a id="line.250"> * &lt;p/&gt;</a>
<span class="sourceLineNo">251</span><a id="line.251"> * This attribute is used &lt;em&gt;only&lt;/em&gt; when constructing the transformation string for block (byte array)</a>
<span class="sourceLineNo">252</span><a id="line.252"> * operations ({@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])}). The</a>
<span class="sourceLineNo">253</span><a id="line.253"> * {@link #getStreamingPaddingSchemeName() streamingPaddingSchemeName} attribute is used when the block cipher is</a>
<span class="sourceLineNo">254</span><a id="line.254"> * used for streaming operations.</a>
<span class="sourceLineNo">255</span><a id="line.255"> * &lt;p/&gt;</a>
<span class="sourceLineNo">256</span><a id="line.256"> * The default value is {@code null} to retain the JCA Provider default.</a>
<span class="sourceLineNo">257</span><a id="line.257"> *</a>
<span class="sourceLineNo">258</span><a id="line.258"> * @return the padding scheme name (as a String) to be used when constructing the</a>
<span class="sourceLineNo">259</span><a id="line.259"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code null} if the JCA Provider default</a>
<span class="sourceLineNo">260</span><a id="line.260"> * padding scheme for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">261</span><a id="line.261"> */</a>
<span class="sourceLineNo">262</span><a id="line.262"> public String getPaddingSchemeName() {</a>
<span class="sourceLineNo">263</span><a id="line.263"> return paddingSchemeName;</a>
<span class="sourceLineNo">264</span><a id="line.264"> }</a>
<span class="sourceLineNo">265</span><a id="line.265"></a>
<span class="sourceLineNo">266</span><a id="line.266"> /**</a>
<span class="sourceLineNo">267</span><a id="line.267"> * Sets the padding scheme name to be used when constructing the</a>
<span class="sourceLineNo">268</span><a id="line.268"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code null} if the JCA Provider default mode for</a>
<span class="sourceLineNo">269</span><a id="line.269"> * the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">270</span><a id="line.270"> * &lt;p/&gt;</a>
<span class="sourceLineNo">271</span><a id="line.271"> * This attribute is used &lt;em&gt;only&lt;/em&gt; when constructing the transformation string for block (byte array)</a>
<span class="sourceLineNo">272</span><a id="line.272"> * operations ({@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])}). The</a>
<span class="sourceLineNo">273</span><a id="line.273"> * {@link #getStreamingPaddingSchemeName() streamingPaddingSchemeName} attribute is used when the block cipher is</a>
<span class="sourceLineNo">274</span><a id="line.274"> * used for streaming operations.</a>
<span class="sourceLineNo">275</span><a id="line.275"> * &lt;p/&gt;</a>
<span class="sourceLineNo">276</span><a id="line.276"> * The default value is {@code null} to retain the JCA Provider default.</a>
<span class="sourceLineNo">277</span><a id="line.277"> * &lt;p/&gt;</a>
<span class="sourceLineNo">278</span><a id="line.278"> * &lt;b&gt;NOTE:&lt;/b&gt; most standard padding schemes are represented by the {@link PaddingScheme PaddingScheme} enum.</a>
<span class="sourceLineNo">279</span><a id="line.279"> * That enum should be used with the {@link #setPaddingScheme paddingScheme} attribute when possible to retain</a>
<span class="sourceLineNo">280</span><a id="line.280"> * type-safety and reduce the possibility of errors. Calling this method however is suitable if the</a>
<span class="sourceLineNo">281</span><a id="line.281"> * {@code PaddingScheme} enum does not represent the desired scheme.</a>
<span class="sourceLineNo">282</span><a id="line.282"> *</a>
<span class="sourceLineNo">283</span><a id="line.283"> * @param paddingSchemeName the padding scheme name to be used when constructing</a>
<span class="sourceLineNo">284</span><a id="line.284"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code null} if the JCA</a>
<span class="sourceLineNo">285</span><a id="line.285"> * Provider default padding scheme for the specified {@link #getAlgorithmName() algorithm}</a>
<span class="sourceLineNo">286</span><a id="line.286"> * should be used.</a>
<span class="sourceLineNo">287</span><a id="line.287"> * @see #setPaddingScheme</a>
<span class="sourceLineNo">288</span><a id="line.288"> */</a>
<span class="sourceLineNo">289</span><a id="line.289"> public void setPaddingSchemeName(String paddingSchemeName) {</a>
<span class="sourceLineNo">290</span><a id="line.290"> this.paddingSchemeName = paddingSchemeName;</a>
<span class="sourceLineNo">291</span><a id="line.291"> //clear out the transformation string so the next invocation will rebuild it with the new padding scheme:</a>
<span class="sourceLineNo">292</span><a id="line.292"> this.transformationString = null;</a>
<span class="sourceLineNo">293</span><a id="line.293"> }</a>
<span class="sourceLineNo">294</span><a id="line.294"></a>
<span class="sourceLineNo">295</span><a id="line.295"> /**</a>
<span class="sourceLineNo">296</span><a id="line.296"> * Sets the padding scheme to be used when constructing the</a>
<span class="sourceLineNo">297</span><a id="line.297"> * {@link javax.crypto.Cipher Cipher} transformation string. A {@code null} value indicates that the JCA Provider</a>
<span class="sourceLineNo">298</span><a id="line.298"> * default padding scheme for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">299</span><a id="line.299"> * &lt;p/&gt;</a>
<span class="sourceLineNo">300</span><a id="line.300"> * This attribute is used &lt;em&gt;only&lt;/em&gt; when constructing the transformation string for block (byte array)</a>
<span class="sourceLineNo">301</span><a id="line.301"> * operations ({@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])}). The</a>
<span class="sourceLineNo">302</span><a id="line.302"> * {@link #setStreamingPaddingScheme streamingPaddingScheme} attribute is used when the block cipher is used for</a>
<span class="sourceLineNo">303</span><a id="line.303"> * streaming operations.</a>
<span class="sourceLineNo">304</span><a id="line.304"> * &lt;p/&gt;</a>
<span class="sourceLineNo">305</span><a id="line.305"> * If the {@link PaddingScheme PaddingScheme} enum does represent your desired scheme, you can set the name explicitly</a>
<span class="sourceLineNo">306</span><a id="line.306"> * via the {@link #setPaddingSchemeName paddingSchemeName} attribute directly. However, because</a>
<span class="sourceLineNo">307</span><a id="line.307"> * {@code PaddingScheme} represents all standard JDK scheme names already, ensure that your underlying JCA Provider</a>
<span class="sourceLineNo">308</span><a id="line.308"> * supports the non-standard name first.</a>
<span class="sourceLineNo">309</span><a id="line.309"> *</a>
<span class="sourceLineNo">310</span><a id="line.310"> * @param paddingScheme the padding scheme to be used when constructing</a>
<span class="sourceLineNo">311</span><a id="line.311"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code null} if the JCA Provider</a>
<span class="sourceLineNo">312</span><a id="line.312"> * default padding scheme for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">313</span><a id="line.313"> */</a>
<span class="sourceLineNo">314</span><a id="line.314"> public void setPaddingScheme(PaddingScheme paddingScheme) {</a>
<span class="sourceLineNo">315</span><a id="line.315"> setPaddingSchemeName(paddingScheme.getTransformationName());</a>
<span class="sourceLineNo">316</span><a id="line.316"> }</a>
<span class="sourceLineNo">317</span><a id="line.317"></a>
<span class="sourceLineNo">318</span><a id="line.318"> /**</a>
<span class="sourceLineNo">319</span><a id="line.319"> * Returns the block cipher's block size to be used when constructing</a>
<span class="sourceLineNo">320</span><a id="line.320"> * {@link javax.crypto.Cipher Cipher} transformation string or {@code 0} if the JCA Provider default block size</a>
<span class="sourceLineNo">321</span><a id="line.321"> * for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">322</span><a id="line.322"> * &lt;p/&gt;</a>
<span class="sourceLineNo">323</span><a id="line.323"> * This attribute is used &lt;em&gt;only&lt;/em&gt; when constructing the transformation string for block (byte array)</a>
<span class="sourceLineNo">324</span><a id="line.324"> * operations ({@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])}). The</a>
<span class="sourceLineNo">325</span><a id="line.325"> * {@link #getStreamingBlockSize() streamingBlockSize} attribute is used when the block cipher is used for</a>
<span class="sourceLineNo">326</span><a id="line.326"> * streaming operations.</a>
<span class="sourceLineNo">327</span><a id="line.327"> * &lt;p/&gt;</a>
<span class="sourceLineNo">328</span><a id="line.328"> * The default value is {@code 0} which retains the JCA Provider default.</a>
<span class="sourceLineNo">329</span><a id="line.329"> *</a>
<span class="sourceLineNo">330</span><a id="line.330"> * @return the block cipher block size to be used when constructing the</a>
<span class="sourceLineNo">331</span><a id="line.331"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code 0} if the JCA Provider default</a>
<span class="sourceLineNo">332</span><a id="line.332"> * block size for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">333</span><a id="line.333"> */</a>
<span class="sourceLineNo">334</span><a id="line.334"> public int getBlockSize() {</a>
<span class="sourceLineNo">335</span><a id="line.335"> return blockSize;</a>
<span class="sourceLineNo">336</span><a id="line.336"> }</a>
<span class="sourceLineNo">337</span><a id="line.337"></a>
<span class="sourceLineNo">338</span><a id="line.338"> /**</a>
<span class="sourceLineNo">339</span><a id="line.339"> * Sets the block cipher's block size to be used when constructing</a>
<span class="sourceLineNo">340</span><a id="line.340"> * {@link javax.crypto.Cipher Cipher} transformation string. {@code 0} indicates that the JCA Provider default</a>
<span class="sourceLineNo">341</span><a id="line.341"> * block size for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">342</span><a id="line.342"> * &lt;p/&gt;</a>
<span class="sourceLineNo">343</span><a id="line.343"> * This attribute is used &lt;em&gt;only&lt;/em&gt; when constructing the transformation string for block (byte array)</a>
<span class="sourceLineNo">344</span><a id="line.344"> * operations ({@link #encrypt(byte[], byte[])} and {@link #decrypt(byte[], byte[])}). The</a>
<span class="sourceLineNo">345</span><a id="line.345"> * {@link #getStreamingBlockSize() streamingBlockSize} attribute is used when the block cipher is used for</a>
<span class="sourceLineNo">346</span><a id="line.346"> * streaming operations.</a>
<span class="sourceLineNo">347</span><a id="line.347"> * &lt;p/&gt;</a>
<span class="sourceLineNo">348</span><a id="line.348"> * The default value is {@code 0} which retains the JCA Provider default.</a>
<span class="sourceLineNo">349</span><a id="line.349"> * &lt;p/&gt;</a>
<span class="sourceLineNo">350</span><a id="line.350"> * &lt;b&gt;NOTE:&lt;/b&gt; block cipher block sizes are very algorithm-specific. If you change this value, ensure that it</a>
<span class="sourceLineNo">351</span><a id="line.351"> * will work with the specified {@link #getAlgorithmName() algorithm}.</a>
<span class="sourceLineNo">352</span><a id="line.352"> *</a>
<span class="sourceLineNo">353</span><a id="line.353"> * @param blockSize the block cipher block size to be used when constructing the</a>
<span class="sourceLineNo">354</span><a id="line.354"> * {@link javax.crypto.Cipher Cipher} transformation string, or {@code 0} if the JCA Provider</a>
<span class="sourceLineNo">355</span><a id="line.355"> * default block size for the specified {@link #getAlgorithmName() algorithm} should be used.</a>
<span class="sourceLineNo">356</span><a id="line.356"> */</a>
<span class="sourceLineNo">357</span><a id="line.357"> public void setBlockSize(int blockSize) {</a>
<span class="sourceLineNo">358</span><a id="line.358"> this.blockSize = Math.max(DEFAULT_BLOCK_SIZE, blockSize);</a>
<span class="sourceLineNo">359</span><a id="line.359"> //clear out the transformation string so the next invocation will rebuild it with the new block size:</a>
<span class="sourceLineNo">360</span><a id="line.360"> this.transformationString = null;</a>
<span class="sourceLineNo">361</span><a id="line.361"> }</a>
<span class="sourceLineNo">362</span><a id="line.362"></a>
<span class="sourceLineNo">363</span><a id="line.363"> /**</a>
<span class="sourceLineNo">364</span><a id="line.364"> * Same purpose as the {@link #getModeName modeName} attribute, but is used instead only for for streaming</a>
<span class="sourceLineNo">365</span><a id="line.365"> * operations ({@link #encrypt(java.io.InputStream, java.io.OutputStream, byte[])} and</a>
<span class="sourceLineNo">366</span><a id="line.366"> * {@link #decrypt(java.io.InputStream, java.io.OutputStream, byte[])}).</a>
<span class="sourceLineNo">367</span><a id="line.367"> * &lt;p/&gt;</a>
<span class="sourceLineNo">368</span><a id="line.368"> * Note that unlike the {@link #getModeName modeName} attribute, the default value of this attribute is not</a>
<span class="sourceLineNo">369</span><a id="line.369"> * {@code null} - it is {@link OperationMode#CBC CBC} for reasons described in the class-level JavaDoc in the</a>
<span class="sourceLineNo">370</span><a id="line.370"> * {@code Streaming} section.</a>
<span class="sourceLineNo">371</span><a id="line.371"> *</a>
<span class="sourceLineNo">372</span><a id="line.372"> * @return the transformation string mode name to be used for streaming operations only.</a>
<span class="sourceLineNo">373</span><a id="line.373"> */</a>
<span class="sourceLineNo">374</span><a id="line.374"> public String getStreamingModeName() {</a>
<span class="sourceLineNo">375</span><a id="line.375"> return streamingModeName;</a>
<span class="sourceLineNo">376</span><a id="line.376"> }</a>
<span class="sourceLineNo">377</span><a id="line.377"></a>
<span class="sourceLineNo">378</span><a id="line.378"> private boolean isModeStreamingCompatible(String modeName) {</a>
<span class="sourceLineNo">379</span><a id="line.379"> return modeName != null &amp;&amp;</a>
<span class="sourceLineNo">380</span><a id="line.380"> !modeName.equalsIgnoreCase(OperationMode.ECB.name()) &amp;&amp;</a>
<span class="sourceLineNo">381</span><a id="line.381"> !modeName.equalsIgnoreCase(OperationMode.NONE.name());</a>
<span class="sourceLineNo">382</span><a id="line.382"> }</a>
<span class="sourceLineNo">383</span><a id="line.383"></a>
<span class="sourceLineNo">384</span><a id="line.384"> /**</a>
<span class="sourceLineNo">385</span><a id="line.385"> * Sets the transformation string mode name to be used for streaming operations only. The default value is</a>
<span class="sourceLineNo">386</span><a id="line.386"> * {@link OperationMode#CBC CBC} for reasons described in the class-level JavaDoc in the {@code Streaming} section.</a>
<span class="sourceLineNo">387</span><a id="line.387"> *</a>
<span class="sourceLineNo">388</span><a id="line.388"> * @param streamingModeName transformation string mode name to be used for streaming operations only</a>
<span class="sourceLineNo">389</span><a id="line.389"> */</a>
<span class="sourceLineNo">390</span><a id="line.390"> public void setStreamingModeName(String streamingModeName) {</a>
<span class="sourceLineNo">391</span><a id="line.391"> if (!isModeStreamingCompatible(streamingModeName)) {</a>
<span class="sourceLineNo">392</span><a id="line.392"> String msg = "mode [" + streamingModeName + "] is not a valid operation mode for block cipher streaming.";</a>
<span class="sourceLineNo">393</span><a id="line.393"> throw new IllegalArgumentException(msg);</a>
<span class="sourceLineNo">394</span><a id="line.394"> }</a>
<span class="sourceLineNo">395</span><a id="line.395"> this.streamingModeName = streamingModeName;</a>
<span class="sourceLineNo">396</span><a id="line.396"> //clear out the streaming transformation string so the next invocation will rebuild it with the new mode:</a>
<span class="sourceLineNo">397</span><a id="line.397"> this.streamingTransformationString = null;</a>
<span class="sourceLineNo">398</span><a id="line.398"> }</a>
<span class="sourceLineNo">399</span><a id="line.399"></a>
<span class="sourceLineNo">400</span><a id="line.400"> /**</a>
<span class="sourceLineNo">401</span><a id="line.401"> * Sets the transformation string mode to be used for streaming operations only. The default value is</a>
<span class="sourceLineNo">402</span><a id="line.402"> * {@link OperationMode#CBC CBC} for reasons described in the class-level JavaDoc in the {@code Streaming} section.</a>
<span class="sourceLineNo">403</span><a id="line.403"> *</a>
<span class="sourceLineNo">404</span><a id="line.404"> * @param mode the transformation string mode to be used for streaming operations only</a>
<span class="sourceLineNo">405</span><a id="line.405"> */</a>
<span class="sourceLineNo">406</span><a id="line.406"> public void setStreamingMode(OperationMode mode) {</a>
<span class="sourceLineNo">407</span><a id="line.407"> setStreamingModeName(mode.name());</a>
<span class="sourceLineNo">408</span><a id="line.408"> }</a>
<span class="sourceLineNo">409</span><a id="line.409"></a>
<span class="sourceLineNo">410</span><a id="line.410"> public String getStreamingPaddingSchemeName() {</a>
<span class="sourceLineNo">411</span><a id="line.411"> return streamingPaddingSchemeName;</a>
<span class="sourceLineNo">412</span><a id="line.412"> }</a>
<span class="sourceLineNo">413</span><a id="line.413"></a>
<span class="sourceLineNo">414</span><a id="line.414"> public void setStreamingPaddingSchemeName(String streamingPaddingSchemeName) {</a>
<span class="sourceLineNo">415</span><a id="line.415"> this.streamingPaddingSchemeName = streamingPaddingSchemeName;</a>
<span class="sourceLineNo">416</span><a id="line.416"> //clear out the streaming transformation string so the next invocation will rebuild it with the new scheme:</a>
<span class="sourceLineNo">417</span><a id="line.417"> this.streamingTransformationString = null;</a>
<span class="sourceLineNo">418</span><a id="line.418"> }</a>
<span class="sourceLineNo">419</span><a id="line.419"></a>
<span class="sourceLineNo">420</span><a id="line.420"> public void setStreamingPaddingScheme(PaddingScheme scheme) {</a>
<span class="sourceLineNo">421</span><a id="line.421"> setStreamingPaddingSchemeName(scheme.getTransformationName());</a>
<span class="sourceLineNo">422</span><a id="line.422"> }</a>
<span class="sourceLineNo">423</span><a id="line.423"></a>
<span class="sourceLineNo">424</span><a id="line.424"> public int getStreamingBlockSize() {</a>
<span class="sourceLineNo">425</span><a id="line.425"> return streamingBlockSize;</a>
<span class="sourceLineNo">426</span><a id="line.426"> }</a>
<span class="sourceLineNo">427</span><a id="line.427"></a>
<span class="sourceLineNo">428</span><a id="line.428"> public void setStreamingBlockSize(int streamingBlockSize) {</a>
<span class="sourceLineNo">429</span><a id="line.429"> this.streamingBlockSize = Math.max(DEFAULT_BLOCK_SIZE, streamingBlockSize);</a>
<span class="sourceLineNo">430</span><a id="line.430"> //clear out the streaming transformation string so the next invocation will rebuild it with the new block size:</a>
<span class="sourceLineNo">431</span><a id="line.431"> this.streamingTransformationString = null;</a>
<span class="sourceLineNo">432</span><a id="line.432"> }</a>
<span class="sourceLineNo">433</span><a id="line.433"></a>
<span class="sourceLineNo">434</span><a id="line.434"> /**</a>
<span class="sourceLineNo">435</span><a id="line.435"> * Returns the transformation string to use with the {@link javax.crypto.Cipher#getInstance} call. If</a>
<span class="sourceLineNo">436</span><a id="line.436"> * {@code streaming} is {@code true}, a block-cipher transformation string compatible with streaming operations will</a>
<span class="sourceLineNo">437</span><a id="line.437"> * be constructed and cached for re-use later (see the class-level JavaDoc for more on using block ciphers</a>
<span class="sourceLineNo">438</span><a id="line.438"> * for streaming). If {@code streaming} is {@code false} a normal block-cipher transformation string will</a>
<span class="sourceLineNo">439</span><a id="line.439"> * be constructed and cached for later re-use.</a>
<span class="sourceLineNo">440</span><a id="line.440"> *</a>
<span class="sourceLineNo">441</span><a id="line.441"> * @param streaming if the transformation string is going to be used for a Cipher performing stream-based encryption or not.</a>
<span class="sourceLineNo">442</span><a id="line.442"> * @return the transformation string</a>
<span class="sourceLineNo">443</span><a id="line.443"> */</a>
<span class="sourceLineNo">444</span><a id="line.444"> protected String getTransformationString(boolean streaming) {</a>
<span class="sourceLineNo">445</span><a id="line.445"> if (streaming) {</a>
<span class="sourceLineNo">446</span><a id="line.446"> if (this.streamingTransformationString == null) {</a>
<span class="sourceLineNo">447</span><a id="line.447"> this.streamingTransformationString = buildStreamingTransformationString();</a>
<span class="sourceLineNo">448</span><a id="line.448"> }</a>
<span class="sourceLineNo">449</span><a id="line.449"> return this.streamingTransformationString;</a>
<span class="sourceLineNo">450</span><a id="line.450"> } else {</a>
<span class="sourceLineNo">451</span><a id="line.451"> if (this.transformationString == null) {</a>
<span class="sourceLineNo">452</span><a id="line.452"> this.transformationString = buildTransformationString();</a>
<span class="sourceLineNo">453</span><a id="line.453"> }</a>
<span class="sourceLineNo">454</span><a id="line.454"> return this.transformationString;</a>
<span class="sourceLineNo">455</span><a id="line.455"> }</a>
<span class="sourceLineNo">456</span><a id="line.456"> }</a>
<span class="sourceLineNo">457</span><a id="line.457"></a>
<span class="sourceLineNo">458</span><a id="line.458"> private String buildTransformationString() {</a>
<span class="sourceLineNo">459</span><a id="line.459"> return buildTransformationString(getModeName(), getPaddingSchemeName(), getBlockSize());</a>
<span class="sourceLineNo">460</span><a id="line.460"> }</a>
<span class="sourceLineNo">461</span><a id="line.461"></a>
<span class="sourceLineNo">462</span><a id="line.462"> private String buildStreamingTransformationString() {</a>
<span class="sourceLineNo">463</span><a id="line.463"> return buildTransformationString(getStreamingModeName(), getStreamingPaddingSchemeName(), 0);</a>
<span class="sourceLineNo">464</span><a id="line.464"> }</a>
<span class="sourceLineNo">465</span><a id="line.465"></a>
<span class="sourceLineNo">466</span><a id="line.466"> private String buildTransformationString(String modeName, String paddingSchemeName, int blockSize) {</a>
<span class="sourceLineNo">467</span><a id="line.467"> StringBuilder sb = new StringBuilder(getAlgorithmName());</a>
<span class="sourceLineNo">468</span><a id="line.468"> if (StringUtils.hasText(modeName)) {</a>
<span class="sourceLineNo">469</span><a id="line.469"> sb.append(TRANSFORMATION_STRING_DELIMITER).append(modeName);</a>
<span class="sourceLineNo">470</span><a id="line.470"> }</a>
<span class="sourceLineNo">471</span><a id="line.471"> if (blockSize &gt; 0) {</a>
<span class="sourceLineNo">472</span><a id="line.472"> sb.append(blockSize);</a>
<span class="sourceLineNo">473</span><a id="line.473"> }</a>
<span class="sourceLineNo">474</span><a id="line.474"> if (StringUtils.hasText(paddingSchemeName)) {</a>
<span class="sourceLineNo">475</span><a id="line.475"> sb.append(TRANSFORMATION_STRING_DELIMITER).append(paddingSchemeName);</a>
<span class="sourceLineNo">476</span><a id="line.476"> }</a>
<span class="sourceLineNo">477</span><a id="line.477"> return sb.toString();</a>
<span class="sourceLineNo">478</span><a id="line.478"> }</a>
<span class="sourceLineNo">479</span><a id="line.479"></a>
<span class="sourceLineNo">480</span><a id="line.480"> /**</a>
<span class="sourceLineNo">481</span><a id="line.481"> * Returns {@code true} if the specified cipher operation mode name supports initialization vectors,</a>
<span class="sourceLineNo">482</span><a id="line.482"> * {@code false} otherwise.</a>
<span class="sourceLineNo">483</span><a id="line.483"> *</a>
<span class="sourceLineNo">484</span><a id="line.484"> * @param modeName the raw text name of the mode of operation</a>
<span class="sourceLineNo">485</span><a id="line.485"> * @return {@code true} if the specified cipher operation mode name supports initialization vectors,</a>
<span class="sourceLineNo">486</span><a id="line.486"> * {@code false} otherwise.</a>
<span class="sourceLineNo">487</span><a id="line.487"> */</a>
<span class="sourceLineNo">488</span><a id="line.488"> private boolean isModeInitializationVectorCompatible(String modeName) {</a>
<span class="sourceLineNo">489</span><a id="line.489"> return modeName != null &amp;&amp;</a>
<span class="sourceLineNo">490</span><a id="line.490"> !modeName.equalsIgnoreCase(OperationMode.ECB.name()) &amp;&amp;</a>
<span class="sourceLineNo">491</span><a id="line.491"> !modeName.equalsIgnoreCase(OperationMode.NONE.name());</a>
<span class="sourceLineNo">492</span><a id="line.492"> }</a>
<span class="sourceLineNo">493</span><a id="line.493"></a>
<span class="sourceLineNo">494</span><a id="line.494"> /**</a>
<span class="sourceLineNo">495</span><a id="line.495"> * Overrides the parent implementation to ensure initialization vectors are always generated if streaming is</a>
<span class="sourceLineNo">496</span><a id="line.496"> * enabled (block ciphers &lt;em&gt;must&lt;/em&gt; use initialization vectors if they are to be used as a stream cipher). If</a>
<span class="sourceLineNo">497</span><a id="line.497"> * not being used as a stream cipher, then the value is computed based on whether or not the currently configured</a>
<span class="sourceLineNo">498</span><a id="line.498"> * {@link #getModeName modeName} is compatible with initialization vectors as well as the result of the configured</a>
<span class="sourceLineNo">499</span><a id="line.499"> * {@link #setGenerateInitializationVectors(boolean) generateInitializationVectors} value.</a>
<span class="sourceLineNo">500</span><a id="line.500"> *</a>
<span class="sourceLineNo">501</span><a id="line.501"> * @param streaming whether or not streaming is being performed</a>
<span class="sourceLineNo">502</span><a id="line.502"> * @return {@code true} if streaming or a value computed based on if the currently configured mode is compatible</a>
<span class="sourceLineNo">503</span><a id="line.503"> * with initialization vectors.</a>
<span class="sourceLineNo">504</span><a id="line.504"> */</a>
<span class="sourceLineNo">505</span><a id="line.505"> @Override</a>
<span class="sourceLineNo">506</span><a id="line.506"> protected boolean isGenerateInitializationVectors(boolean streaming) {</a>
<span class="sourceLineNo">507</span><a id="line.507"> return streaming || super.isGenerateInitializationVectors() &amp;&amp; isModeInitializationVectorCompatible(getModeName());</a>
<span class="sourceLineNo">508</span><a id="line.508"> }</a>
<span class="sourceLineNo">509</span><a id="line.509"></a>
<span class="sourceLineNo">510</span><a id="line.510"> @Override</a>
<span class="sourceLineNo">511</span><a id="line.511"> protected byte[] generateInitializationVector(boolean streaming) {</a>
<span class="sourceLineNo">512</span><a id="line.512"> if (streaming) {</a>
<span class="sourceLineNo">513</span><a id="line.513"> String streamingModeName = getStreamingModeName();</a>
<span class="sourceLineNo">514</span><a id="line.514"> if (!isModeInitializationVectorCompatible(streamingModeName)) {</a>
<span class="sourceLineNo">515</span><a id="line.515"> String msg = "streamingMode attribute value [" + streamingModeName + "] does not support " +</a>
<span class="sourceLineNo">516</span><a id="line.516"> "Initialization Vectors. Ensure the streamingMode value represents an operation mode " +</a>
<span class="sourceLineNo">517</span><a id="line.517"> "that is compatible with initialization vectors.";</a>
<span class="sourceLineNo">518</span><a id="line.518"> throw new IllegalStateException(msg);</a>
<span class="sourceLineNo">519</span><a id="line.519"> }</a>
<span class="sourceLineNo">520</span><a id="line.520"> } else {</a>
<span class="sourceLineNo">521</span><a id="line.521"> String modeName = getModeName();</a>
<span class="sourceLineNo">522</span><a id="line.522"> if (!isModeInitializationVectorCompatible(modeName)) {</a>
<span class="sourceLineNo">523</span><a id="line.523"> String msg = "mode attribute value [" + modeName + "] does not support " +</a>
<span class="sourceLineNo">524</span><a id="line.524"> "Initialization Vectors. Ensure the mode value represents an operation mode " +</a>
<span class="sourceLineNo">525</span><a id="line.525"> "that is compatible with initialization vectors.";</a>
<span class="sourceLineNo">526</span><a id="line.526"> throw new IllegalStateException(msg);</a>
<span class="sourceLineNo">527</span><a id="line.527"> }</a>
<span class="sourceLineNo">528</span><a id="line.528"> }</a>
<span class="sourceLineNo">529</span><a id="line.529"> return super.generateInitializationVector(streaming);</a>
<span class="sourceLineNo">530</span><a id="line.530"> }</a>
<span class="sourceLineNo">531</span><a id="line.531">}</a>
</pre>
</div>
</main>
</body>
</html>