Подтвердить что ты не робот

Какое разрешение установить, чтобы избежать ошибок с Security-Manager с https-URLS?

В программном обеспечении для клиента мы должны прочитать данные URL для анализа их содержимого. Также клиенту необходимо активировать Tomcat-Security-Manager, чтобы позволить Java-политикам контролировать, что делает программа.

Теперь, при чтении URL-адресов исключение "javax.net.ssl.SSLKeyException: секретная ошибка RSA premaster" происходит, но только при определенных условиях:

  • если URL-адрес HTTPS, но не для HTTP
  • если активирован Security-Manager, а не когда он деактивирован или если в глобальном грантовом блоке установлен AllPermission
  • только с Java 6, а не с Java 7 (заказчику в настоящее время требуется Java 6)
  • только с Tomcat6, а не с Tomcat 7 (заказчику в настоящий момент нужен Tomcat 6)

Нарушение безопасности происходит где-то в Java-коде, AllPermission, ограниченный нашей кодовой базой, не мешает ошибке.

Итак, есть ли у кого-то идея, какое разрешение установить для Java 6, чтобы она могла обрабатывать HTTPS?

Дополнительная информация: он работает внутри tomcat, на Debian-Linux с OpenJDK.

EDIT: я добавил Java-Param "-Djava.security.debug = доступ, сбой" к Tomcats/etc/default/tomcat6 в переменной JAVA_OPTS. Но в журналах у меня нет дополнительных сообщений. Возможно ли, что код запрашивает разрешения перед их запуском?

EDIT2: я нашел правильное место и получил полный стек (удалены конкретные части клиента):

javax.net.ssl.SSLKeyException: RSA premaster secret error

            at [...]
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:537)
            at java.lang.Thread.run(Thread.java:701)
    Caused by: java.security.NoSuchAlgorithmException: SunTlsRsaPremasterSecret KeyGenerator not available
            at javax.crypto.KeyGenerator.<init>(KeyGenerator.java:141)
            at javax.crypto.KeyGenerator.getInstance(KeyGenerator.java:191)
            ... 14 more

EDIT3: До сих пор я был в предположении, что URL-адрес Java-класса использовался для доступа к содержимому ресурса. Но это неверно. Он использует от Grails-Code объект Groovy -URL с методом getText():

new URL(params.url).text

Ошибка в этой строке. Это Grails-версия 2.2.4.

4b9b3361

Ответ 1

Решение после нескольких комментариев и подтверждения OP разрешения (сводка)

Основной причиной является наличие sunjce_provider.jar в нескольких местах. Это было открыто OP после того, как оно было предложено как один из нескольких возможных причин (см. Самый конец этого ответа и след комментария). Согласно комментарию OP:

У меня есть sunjce_provider.jar в нескольких каталогах. Я попытался предоставить все три места для Java 6, хотя, очевидно, только один из них - JAVA_HOME - и это сработало. Как-то используется одно из других мест, хотя оно не находится в java.ext.dirs-property

Поэтому разрешение в этом случае состояло в том, чтобы убедиться, что приложение имеет права доступа к правильной копии sunjce_provider.jar

Я оставил основные моменты из своего первоначального ответа и комментарии, которые помогли с диагнозом ниже для тех, кто находит это позже

Оригинальный ответ и комментарии, которые привели к решению

  • Это не произойдет с http, потому что ваше веб-приложение (то есть клиент для этого соединения, даже если оно работает в tomcat) не нуждается в создании ключа в этой конфигурации.

  • Тот факт, что это происходит только в том случае, когда SecurityManager включен, но не отключен или глобальный AllPermission предлагает ошибку разрешения файла. Это говорит о том, что это не проблема с длиной ключа (например, упомянутая здесь )

Другое аналогичные сообщает в web указывают, что вероятной основной причиной является недостающая банка (обычно цитируется sunjce_provider.jar). Трассировка стека подтверждает, что причиной основной причины является NoSuchAlgorithmException, где KeyGenerator ищет алгоритм SunTlsRsaPremasterSecret и не может его найти. В вашем случае, поскольку это происходит только с конкретной конфигурацией SecurityManager, это может быть банкомат недоступный (из-за разрешений безопасности).

Я предполагаю, что вы не включили разрешения grant codeBase в правильную директорию, содержащую банку, необходимую для вашего алгоритма RSA-кейгена. Мой предложенный курс действий состоял бы в том, чтобы пройти через структуру каталогов webapp и JRE, чтобы найти, где хранятся фреймы времени выполнения, и гарантировать, что у них есть разрешения grant ed в catalina.policy.

В конфигурации по умолчанию - например, вы должны увидеть где-нибудь

// These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
        permission java.security.AllPermission;
};

Подробнее о том, что это означает, точно см. в этом разделе менеджера безопасности tomcat "How To". Вам нужно проверить несколько вещей - убедитесь, что ${java.home}/jre/lib/ext/ находится там, где находятся ваши баннеры времени выполнения. Если нет - измените путь, указывающий на нужное место (он , где они находятся в моей версии OpenJDK 6 - сборка 27). В частности, вы должны увидеть там sunjce_provider.jar и sunpkcs11.jar. Убедитесь, что вышеуказанный раздел существует в файле политики.

Возможно, код зависит от некоторых банок, которые находятся внутри вашего webapp - например. в ${catalina.base}/path/to/your/webapp/WEB-INF/classes/ - в этом случае вам необходимо предоставить разрешения для этого каталога.


Другие проблемы, вызывающие такие же или подобные симптомы

  • Приложение, которое не может найти или получить доступ к sunpkcs11.jar, предоставит такое же сообщение об ошибке (проверено в системе Ubuntu + openjdk6 + tomcat6). Вероятно, дублированные копии этой банки также будут.

  • проверить /etc/java-6-openjdk/security/java.security. Он должен указать поставщиков там - проверьте там что-то вроде security.provider.n = sun.security.pkcs11.SunPKCS11, если эта строка отсутствует, вы также получите эту ошибку (подтвержденную в той же системе)

  • Этот отчет об ошибке в Debian рассказывает о проблемах с расположением банок при работе под SecurityManager


Отладочный комментарий

В соответствии с другим ответом вы можете попробовать добавить -Djava.security.debug=access,failure в CATALINA_OPTS или JAVA_OPTS в свой файл catalina.sh, чтобы включить отладку, - которая должна войти в систему catalina.out по умолчанию (или где бы вы не установили регистрацию через CATALINA_OUT в catalina.sh. Вы должны видеть вывод SecurityManager там.

Вы также можете попробовать -Djava.security.debug=all. You will get a huge catalina.out`, но вы можете grep для слов, которые могут помочь (например, "сбой"!!!)


Следуйте коду из трассировки стека

Ваше исключение вызывается здесь. Глядя на то, как это исключение можно было бы выбросить - этот метод должен возвращать значение null. Это ласточки Exception s- что не очень приятно и затрудняет диагностику того, какая часть этого кода терпит неудачу. Мои деньги будут на этой строке - где canUseProvider() может вернуться false. Это все указывает на то, что кран поставщика не может быть недоступен по какой-либо причине.

Я предполагаю, что вы не видели нарушений доступа на выходе, даже с -Djava.security.debug=access,failure. Вы можете попробовать -Djava.security.debug=all, хотя это может привести к простому возникновению более неулокального ведения журнала. Если нарушение прав доступа отсутствует, вы можете иметь две версии этой банки в вашем пути к классам, и среда выполнения имеет доступ (или пытается получить доступ к неправильному). Случай, подобный этому, описан в этом Q/A.

Ответ 2

Простым способом обнаружения всех необходимых разрешений является запуск с аргументом

-Djava.security.debug=access,failure

После этого вам будет предоставлена ​​полная информация о каждом неудачном доступе к безопасности, о домене защиты, который был в силе, и т.д.