com.sun.faces.ClientStateSavingPassword - recommendations for actual password?
Asked Answered
B

1

10

In all of the reference pages I've found with regards to encrypting the ViewState, the only comment on the password is "your password here".

Are there any recommendations regarding the length / complexity of the password that we should use?

Bromo answered 30/1, 2015 at 7:42 Comment(0)
C
21

Depends on Mojarra version. It had several flaws/fails in earlier versions.

In Mojarra 1.2.x - 2.1.18, it was never actually used. The JNDI entry name was namely incorrectly documented. It was documented as com.sun.faces.ClientStateSavingPassword (with same prefix as Mojarra's other web.xml context parameters), but the code actually checks for ClientStateSavingPassword. You should then register it on that name instead.

<env-entry>
    <env-entry-name>ClientStateSavingPassword</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>[Your Password]</env-entry-value>
</env-entry>

Otherwise, the client state is actually not encrypted.

In Mojarra 1.2.x - 2.0.3, the password will be used as a SecureRandom seed to generate a DES algorithm key. So, generally, the same rules apply as to "real world" passwords. Only, this can be easily compromised if the password is "too easy" and the attacker successfully guesses/bruteforces/figures the password.

In Mojarra 2.0.4 - 2.1.x, they changed the algorithm from DES to AES and the code now don't actually use the provided password anymore to generate the key (to prevent potential comprisions). Instead, a completely random key is generated, which is more safe. The JNDI entry now basically controls whether the client state should be encrypted or not. In other words, it behaves now like a boolean configuration entry. It thus absolutely doesn't matter anymore which password you use.

<env-entry>
    <env-entry-name>ClientStateSavingPassword</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>[Any value is interpreted as boolean=true to enable encryption]</env-entry-value>
</env-entry>

In Mojarra 2.1.19 - 2.1.x, they fixed the code to align the documentation on JNDI entry name. So you could use the documented JNDI entry name:

<env-entry>
    <env-entry-name>com.sun.faces.ClientStateSavingPassword</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>[Any value is interpreted as boolean=true to enable encryption]</env-entry-value>
</env-entry>

However, this still doesn't affect the AES key, which was changed since 2.0.4, it still basically only enables/disables the encryption.

In Mojarra 2.2.0 - 2.3.x, as part of JSF 2.2 specification (chapter 7.8.2), client side state is now by default always encrypted. It will only be disabled when web.xml context parameter com.sun.faces.disableClientStateEncryption is set with value true. It still uses AES algorithm with a completely random key. The JNDI entry com.sun.faces.ClientStateSavingPassword is now not used anymore.

In Mojarra 2.2.6 - 2.3.x, they added as per issue 3087 a new JNDI entry which allows you to specify the AES key in Base64 encoded format, the jsf/ClientSideSecretKey. This is part of the bugfix on failing client side state when a JSF webapp is used in cluster environment, because each server used a different AES key which would only cause a ERROR: MAC did not verify! when state is restored in a different server than the one which saved the state, as described in issue 2557.

<env-entry>
    <env-entry-name>jsf/ClientSideSecretKey</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>[AES key in Base64 format]</env-entry-value>
</env-entry>

You can use this AES key generator to generate one (refresh the page to regenerate), or use below snippet to generate your own Base64-encoded AES256 key:

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // Use 128 for AES128 (when server don't have JCE installed).
String key = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
System.out.println(key); // Prints AES key in Base64 format.
Cruciform answered 2/2, 2015 at 12:7 Comment(11)
About as definitive as I could hope for :) I'll go check exactly which version is running - thanks. I've got 16 hours to go until I can award the bounty, so I'll post it on this answer then.Bromo
You're welcome. You can also just wait until the bounty period expires. Generally, you've most chance on upvotes in the last day of the bounty (as this question then floats in top of "featured" list), this way you can earn the points back.Cruciform
Given that I know that it wasn't encrypted before, and that it used com.sun.faces.ClientStateSavingPassword, it seems likely that I fall in the 2.1.19 - 2.1.x block. We're in a clustered environment - am I likely to run into issues with different AES keys being used on each server?Bromo
Unfortunately, yes, unless the loadbalancer is configured to stick to one specific node per session (or per javax.faces.ViewState request parameter, if possible). Given that you're using JSF 2.1 (and thus not 2.0), you should technically be able to effortlessly upgrade it to JSF 2.2 on same environment (use then at least Mojarra 2.2.6).Cruciform
@Cruciform [AES key in Base64 format] actually just means 128/192/256 random bits in base64 here, doesn't it? Or is there some additional format restriction that applies?Woolsack
Sidenote, @BalusC: I've been experiencing: jsf.externalcontext.flash.bad.cookie=JSF1094: Could not decode flash data from incoming cookie value {0}. Processing will continue, but the flash is unavailable for this request. Could this also be caused by my lacking the jsf/ClientSideSecretKey in web.xml? I'm on 2.2.17 btw. It seems to me that when the application is restarted/redeployed it would then not be able to decrypt any existing cookie.Zachariah
@matsa: nope, it's using jsf/FlashSecretKey.Cruciform
Well, I've never heard of jsf/FlashSecretKey so that helps! Google seems to fail me, could you direct me to documentation on this?Zachariah
@matsa: github.com/eclipse-ee4j/mojarra/blob/2.3/impl/src/main/java/com/… :)Cruciform
@Cruciform Thanks! It's probably time to create new question instead of spamming this old thread.Zachariah
For others: stackoverflow.com/questions/67089149/…Zachariah

© 2022 - 2024 — McMap. All rights reserved.