com.sun.faces.ClientStateSavingPassword - рекомендации для реального пароля?
На всех ссылочных страницах, которые я нашел в отношении шифрования ViewState, единственным комментарием к паролю является "ваш пароль здесь".
Есть ли какие-либо рекомендации относительно длины / сложности пароля, который мы должны использовать?
1 ответ
Зависит от версии Мохарры. В предыдущих версиях было несколько недостатков / сбоев.
В Mojarra 1.2.x - 2.1.18 он никогда не использовался. Имя записи JNDI было неправильно задокументировано. Это было задокументировано как 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 пароль будет использоваться как SecureRandom
seed для генерации ключа алгоритма DES. Так что, как правило, применяются те же правила, что и к паролям "реального мира". Только это может быть легко скомпрометировано, если пароль "слишком прост" и злоумышленник успешно угадывает / подбирает / вычисляет пароль.
В 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), состояние на стороне клиента теперь по умолчанию всегда зашифровано. Он будет отключен только тогда, когда web.xml
параметр контекста com.sun.faces.disableClientStateEncryption
устанавливается со значением true
, Он по- прежнему использует алгоритм AES с совершенно случайным ключом. Запись JNDI com.sun.faces.ClientStateSavingPassword
больше не используется
В Mojarra 2.2.6 - 2.3.x они добавили в соответствии с проблемой 3087 новую запись JNDI, которая позволяет вам указать ключ AES в кодированном формате Base64, jsf/ClientSideSecretKey
, Это является частью исправления при сбое состояния на стороне клиента, когда веб-приложение JSF используется в кластерной среде, поскольку каждый сервер использует свой ключ 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 для его генерации (обновить страницу для регенерации) или использовать приведенный ниже фрагмент кода для генерации собственного ключа AES256 с кодировкой Base64:
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.