com.sun.faces.ClientStateSavingPassword - 对实际密码的建议?
com.sun.faces.ClientStateSavingPassword - recommendations for actual password?
在我找到的所有关于加密 ViewState 的参考页面中,关于密码的唯一注释是 "your password here"。
对于我们应该使用的密码的长度/复杂性,是否有任何建议?
取决于 Mojarra 版本。它在早期版本中有几个flaws/fails。
在 Mojarra 1.2.x - 2.1.18 中,它从未被实际使用过。 JNDI 条目名称被错误地记录下来。 documented as com.sun.faces.ClientStateSavingPassword
(with same prefix as Mojarra's other web.xml
context parameters), but the code actually 检查 ClientStateSavingPassword
。然后你应该用那个名字注册它。
<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>
否则,客户端状态实际上没有加密。
在Mojarra 1.2.x - 2.0.3中,密码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如果密码是"too easy"并且攻击者成功guesses/bruteforces/figures密码。
在 Mojarra 2.0.4 - 2.1.x 中,它们 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 更安全。 JNDI 条目现在基本上控制客户端状态是否应该加密。换句话说,它现在的行为就像一个布尔配置条目。因此,您使用哪个密码完全无关紧要。
<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>
在 Mojarra 2.1.19 - 2.1.x 中,他们 fixed 将代码对齐 JNDI 条目名称上的文档。因此,您可以使用已记录的 JNDI 条目名称:
<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>
然而,这仍然不影响 AES 密钥,自 2.0.4 以来已更改,它仍然基本上只是 enables/disables 加密。
在 Mojarra 2.2.0 - 2.3.x 中,作为 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 的一部分。 JNDI 条目 com.sun.faces.ClientStateSavingPassword
现在 不再 使用。
在 Mojarra 2.2.6 - 2.3.x 中,他们根据 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>
您可以使用这个 AES key generator to generate one (refresh the page to regenerate), or use below snippet to generate your own Base64-encoded AES256 键:
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.
在我找到的所有关于加密 ViewState 的参考页面中,关于密码的唯一注释是 "your password here"。
对于我们应该使用的密码的长度/复杂性,是否有任何建议?
取决于 Mojarra 版本。它在早期版本中有几个flaws/fails。
在 Mojarra 1.2.x - 2.1.18 中,它从未被实际使用过。 JNDI 条目名称被错误地记录下来。 documented as com.sun.faces.ClientStateSavingPassword
(with same prefix as Mojarra's other web.xml
context parameters), but the code actually 检查 ClientStateSavingPassword
。然后你应该用那个名字注册它。
<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>
否则,客户端状态实际上没有加密。
在Mojarra 1.2.x - 2.0.3中,密码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如果密码是"too easy"并且攻击者成功guesses/bruteforces/figures密码。
在 Mojarra 2.0.4 - 2.1.x 中,它们 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 更安全。 JNDI 条目现在基本上控制客户端状态是否应该加密。换句话说,它现在的行为就像一个布尔配置条目。因此,您使用哪个密码完全无关紧要。
<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>
在 Mojarra 2.1.19 - 2.1.x 中,他们 fixed 将代码对齐 JNDI 条目名称上的文档。因此,您可以使用已记录的 JNDI 条目名称:
<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>
然而,这仍然不影响 AES 密钥,自 2.0.4 以来已更改,它仍然基本上只是 enables/disables 加密。
在 Mojarra 2.2.0 - 2.3.x 中,作为 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 的一部分。 JNDI 条目 com.sun.faces.ClientStateSavingPassword
现在 不再 使用。
在 Mojarra 2.2.6 - 2.3.x 中,他们根据 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>
您可以使用这个 AES key generator to generate one (refresh the page to regenerate), or use below snippet to generate your own Base64-encoded AES256 键:
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.