在我找到的所有关于加密 ViewState 的参考页面中,对密码的唯一评论是“您的密码在这里”。
关于我们应该使用的密码的长度/复杂性有什么建议吗?
在我找到的所有关于加密 ViewState 的参考页面中,对密码的唯一评论是“您的密码在这里”。
关于我们应该使用的密码的长度/复杂性有什么建议吗?
取决于 Mojarra 版本。它在早期版本中有几个缺陷/失败。
在Mojarra 1.2.x - 2.1.18中,它从未真正使用过。JNDI 条目名称即被错误地记录。它被记录为(与Mojarra 的其他上下文参数com.sun.faces.ClientStateSavingPassword
具有相同的前缀),但代码实际上检查. 然后,您应该改为使用该名称注册它。web.xml
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中,密码将用作生成DES 算法密钥的SecureRandom
种子。因此,通常,相同的规则适用于“真实世界”密码。只是,如果密码“太简单”并且攻击者成功猜测/暴力破解/计算密码,这很容易被破坏。
在Mojarra 2.0.4 - 2.1.x中,他们将算法从 DES 更改为 AES,现在代码实际上不再使用提供的密码来生成密钥(以防止潜在的压缩)。而是生成一个完全随机的密钥,这样更安全。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中,他们修复了代码以对齐 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>
但是,这仍然不会影响自 2.0.4 以来更改的 AES 密钥,它仍然基本上只启用/禁用加密。
在Mojarra 2.2.0 - 2.3.x中,作为JSF 2.2 规范(第 7.8.2 章)的一部分,客户端状态现在默认始终是加密的。web.xml
仅当context 参数com.sun.faces.disableClientStateEncryption
设置为 value时,它才会被禁用true
。它仍然使用带有完全随机密钥的 AES 算法。com.sun.faces.ClientStateSavingPassword
现在不再使用JNDI 条目。
在Mojarra 2.2.6 - 2.3.x中,他们根据issue 3087添加了一个新的 JNDI 条目,允许您以 Base64 编码格式指定 AES 密钥,jsf/ClientSideSecretKey
. 这是在集群环境中使用 JSF webapp 时客户端状态失败的错误修复的一部分,因为每个服务器使用不同的 AES 密钥,这只会导致ERROR: MAC did not verify!
当状态在与保存状态的服务器不同的服务器中恢复时,如问题 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 密钥生成器生成一个(刷新页面以重新生成),或使用以下代码段生成您自己的Base64编码的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.