10

在我找到的所有关于加密 ViewState 的参考页面中,对密码的唯一评论是“您的密码在这里”。

关于我们应该使用的密码的长度/复杂性有什么建议吗?

4

1 回答 1

21

取决于 Mojarra 版本。它在早期版本中有几个缺陷/失败。

Mojarra 1.2.x - 2.1.18中,它从未真正使用过。JNDI 条目名称即被错误地记录。它被记录为(与Mojarra 的其他上下文参数com.sun.faces.ClientStateSavingPassword具有相同的前缀),但代码实际上检查. 然后,您应该改为使用该名称注册它。web.xmlClientStateSavingPassword

<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.
于 2015-02-02T12:07:01.327 回答