When using client side state saving, the UI object model is serialized and rendered with the response. This is behavior controlled by the following context parameter.
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
One consequence of client side state saving is that anyone with a decoder and some time to kill can reconstruct the UI object model on the client side. This can be a problem for those of us who make use of the excellent
t:saveState tag.
Enabling encryption is as easy as putting the following context parameter in your deployment descriptor. There are two things to note here. First, this uses the default encryption algorithm,
DES, so the secret must have a size of eight. Second, although the secret is actually "76543210", we do not put this directly in the deployment descriptor. Instead, we place it's base 64 encoded value. This annoying extra step in the process is required so that secrets are not limited to printable character values.
<context-param>
<param-name>org.apache.myfaces.secret</param-name>
<param-value>NzY1NDMyMTA=</param-value>
</context-param>
An example command line shows how you can obtain the base 64 encoded value of any String.
java -cp .\myfaces-all.jar;.\commons-logging.jar;commons-codec.jar org.apache.myfaces.util.StateUtils abcd1234
There are stronger forms of encryption. Below is an example of how one would use the
BlowFish algorithm with a secret of size 16.
<context-param>
<param-name>org.apache.myfaces.secret</param-name>
<param-value>NzY1NDMyMTA3NjU0MzIxMA</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.algorithm</param-name>
<param-value>Blowfish</param-value>
</context-param>
When using stronger forms of encryption, you may get the following exception on the second HTTP request after placing this in your deployment descriptor
InvalidKeyException: Illegal key size or default parameters
or the following exception on your first HTTP request
java.lang.SecurityException: Unsupported keysize or algorithm parameters
This most likely means that you must go to a place like
http://java.sun.com/j2se/1.4.2/download.html and get the unlimited jursidiction policy files. You will basically need to replace a few jars under <JAVA_HOME>jre\lib\security . All of the following examples require unlimited jurisdiction policy files.
Here is an example of using
3DES with a secret of size 24.
<context-param>
<param-name>org.apache.myfaces.secret</param-name>
<param-value>MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIz</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.algorithm</param-name>
<param-value>DESede</param-value>
</context-param>
All Three examples shown so far use the default encryption mode, ECB. CBC mode is generally regarded as a better. CBC mode encryption however requires what is known as an initialization vector (VI). You do not need to be familiar with these concepts. Just keep in mind that using CBC in combination with a VI is stronger then plain ECB when inputs (in our case, serialized streams of UIComponent values) have patterns (not design patterns!).
Below is an example of using
AES encryption with a secret of size 24. There are two new context parameters. First, the org.apache.myfaces.algorithm.parameters context parameter is being used to override the default mode. Second, because the mode is now CBC, we MUST supply an IV as well using the org.apache.myfaces.algorithm.iv context parameter. The IV, like the secret, is base 64 encoded (and for the same reason). The real value of the IV in this example is "7654321076543210" .
<context-param>
<param-name>org.apache.myfaces.secret</param-name>
<param-value>MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIz</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.algorithm</param-name>
<param-value>AES</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.algorithm.parameters</param-name>
<param-value>CBC/PKCS5Padding</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.algorithm.iv</param-name>
<param-value>NzY1NDMyMTA3NjU0MzIxMA==</param-value>
</context-param>
If you are using log4j, the following line in log4j.properties can be used to debug encryption at runtime.
log4j.logger.org.apache.myfaces.shared_impl.util=debug
This feature was added after the MyFaces 1.1.1 release.
In the rare case of your JCA provider lacking a thread safe
javax.crypto.spec.SecretKeySpec, it is advised that you disable SecretKey caching by specifying the following context parameter in the deployment descriptor.
<context-param>
<param-name>org.apache.myfaces.secret.cache</param-name>
<param-value>false</param-value>
</context-param>