Com.sun.faces.ClientStateSavingPassword - рекомендации для фактического пароля?

На всех ссылочных страницах, которые я нашел в отношении шифрования ViewState, единственным комментарием к паролю является "ваш пароль здесь".

Есть ли какие-либо рекомендации относительно длины/сложности пароля, который мы должны использовать?

Ответ 1

Зависит от версии Моджарры. В ранних версиях он имел несколько ошибок/неудач.

В Mojarra 1.2.x - 2.1.18 он никогда не использовался. Имя записи JNDI было неправильно документировано. Это задокументировано как com.sun.faces.ClientStateSavingPassword (с тем же префиксом, что и Mojarra other 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 пароль будет использоваться как SecureRandom seed, чтобы сгенерировать ключ алгоритма DES. Таким образом, как правило, применяются те же правила, что и пароли "real world" . Только, это может быть легко скомпрометировано, если пароль "слишком прост", и злоумышленник успешно угадывает/bruteforces/рисует пароль.

В 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>

Однако это все еще не влияет на ключ AES, который был изменен с версии 2.0.4, но по-прежнему в основном включает/отключает шифрование.

В Mojarra 2.2.0 - 2.3.x, как часть спецификация JSF 2.2 (глава 7.8. 2), состояние клиентской стороны теперь по умолчанию always зашифровано. Он будет отключен только в том случае, если web.xml параметр контекста com.sun.faces.disableClientStateEncryption установлен со значением true. все еще использует алгоритм AES с полностью случайным ключом, Запись JNDI com.sun.faces.ClientStateSavingPassword теперь больше не.

В Mojarra 2.2.6 - 2.3.x они добавили по issue 3087 новую запись JNDI который позволяет вам указать ключ AES в кодированном формате Base64, jsf/ClientSideSecretKey. Это часть исправления ошибки при отказе на стороне клиента, когда в среде кластера используется веб-приложение JSF, поскольку каждый сервер использовал другой ключ AES, который вызвал бы только ERROR: MAC did not verify! при восстановлении состояния на другом сервере, чем тот, который был сохранен состояние, как описано в 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 для генерации одного (обновить страницу для регенерации) или использовать ниже фрагмент, чтобы создать собственный 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.