设置哪个权限,以避免使用 https-URLS 的 Security-Manager 出错?
Which permission to set, to avoid error with Security-Manager with https-URLS?
在面向客户的软件中,我们必须阅读给定的 URLs 来解析他们的内容。此外,客户需要激活 Tomcat-Security-Manager 以让 Java-Policies 控制程序的功能。
现在,读取 URLs 异常 "javax.net.ssl.SSLKeyException: RSA premaster secret error" 发生,但仅在特定条件下发生:
- 如果 URL 是 HTTPS 而不是 HTTP
- 如果安全管理器被激活,而不是在它被停用时或
如果在全局授权块中设置了 AllPermission
- 只有Java6,没有Java7(客户目前需要Java6)
- 只有Tomcat6,没有Tomcat7(客户目前需要Tomcat6)
安全违规发生在 Java-Code 的某处,限制在我们的代码库中的 AllPermission 并不能阻止错误。
所以,有没有人有想法,为Java 6 设置哪个权限,以便它可以处理HTTPS?
其他信息:运行 在 tomcat 中,在带有 OpenJDK 的 Debian-Linux 上。
编辑:我将 Java-Param“-Djava.security.debug=access,failure”添加到变量 JAVA_OPTS 中的 Tomcats /etc/default/tomcat6。但是在日志中我没有其他消息。代码可能会在触发之前询问权限吗?
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:到目前为止,我假设 Java-class URL 用于访问资源的内容。但这是不正确的。它使用来自 Grails-Code 的 Groovy-URL-object 和 getText()-method:
new URL(params.url).text
此行发生错误。它是 Grails 版本 2.2.4.
发现所有必需权限的简单方法是 运行 使用参数
-Djava.security.debug=access,failure
然后您将获得有关每次失败的安全访问、生效的保护域等的完整信息。
几条评论和 OP 确认解决方案(摘要)后的解决方案
根本原因是在多个位置存在 sunjce_provider.jar
。这是在被建议为许多可能的根本原因之一之后被 OP 发现的(请参阅此答案的最后和评论线索)。根据 OP 的评论:
I have the sunjce_provider.jar in multiple directories. I tried to give all three locations for Java 6 the rights, although clearly only one is JAVA_HOME - and it worked. Somehow one of the other locations is used, although it isn't in the java.ext.dirs-property
因此,本案例的解决方案是确保该应用有权访问 sunjce_provider.jar
的正确副本
我把我原来的回答的要点和有助于诊断的评论留在下面,供以后发现的人使用
导致解决方案的原始答案和评论
http
不会发生这种情况,因为您的 Web 应用程序(即此连接的客户端,即使它在 tomcat 中是 运行)不需要在此配置中生成密钥。
它仅在启用 SecurityManager 时发生,但在禁用或使用全局 AllPermission 时不会发生,这表明它是文件权限错误。这表明这不是密钥长度的问题(例如 mentioned here)
其他 similar reports on the web 表示可能的根本原因是缺少 jar(通常引用 sunjce_provider.jar)。堆栈跟踪确认根本原因异常是 NoSuchAlgorithmException
,其中 KeyGenerator
正在寻找算法 SunTlsRsaPremasterSecret
但找不到它。在你的情况下,因为这只发生在特定的 SecurityManager
配置中,它可能是一个 inaccessible jar(由于安全权限) .
我的猜测是您没有启用对正确目录的 grant codeBase
权限,该目录包含您的 RSA 密钥生成算法所需的 jar。我建议的做法是检查您的 webapp 和 JRE 目录结构,以找到运行时 jar 的保存位置,并确保它们在 catalina.policy
.
中具有 grant
ed 权限
在默认配置中——例如——你应该在某处看到
// These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
permission java.security.AllPermission;
};
有关这意味着什么的详细信息,请参阅 tomcat 安全管理器“How To”的 this section。您需要检查一些事项 - 确保 ${java.home}/jre/lib/ext/
是您的运行时 jar 所在的位置。如果不是 - 更改路径以指向正确的位置(它 是 它们在我的 OpenJDK 6 版本 - build 27 上的位置。特别是你应该在那里看到 sunjce_provider.jar
和 sunpkcs11.jar
。确保以上部分存在于您的策略文件中。
代码可能取决于您的网络应用程序中的某些 jar - 例如在 ${catalina.base}/path/to/your/webapp/WEB-INF/classes/
中 - 在这种情况下,您需要授予对该目录的权限。
导致相同或相似症状的其他问题
App being unabled find or accesssunpkcs11.jar
也会报同样的错误信息(在Ubuntu+openjdk6+tomcat6系统上验证)。该 jar 的副本很可能也会。
检查 /etc/java-6-openjdk/security/java.security
。它应该在那里列出提供者 - 检查那里是否有类似 security.provider.n = sun.security.pkcs11.SunPKCS11
的行 - 如果缺少该行,你也会收到此错误(在同一系统上验证)
这个Debian bug report讨论了运行在SecurityManager
下jar的位置问题
调试评论
根据其他答案,您可以尝试将 -Djava.security.debug=access,failure
添加到 CATALINA_OPTS
或 catalina.sh 中的 JAVA_OPTS
以启用调试 - 应记录到 catalina.out
默认情况下(或在 catalina.sh 中通过 CATALINA_OUT
设置日志记录的任何地方。您应该会看到 SecurityManager
的输出。
您也可以尝试 -Djava.security.debug=all. You will get a huge
catalina.out`,但您可以 grep 查找可能有帮助的词(例如“fail”!!!)
遵循堆栈跟踪中的代码
您的异常被抛出 here. Looking at how that exception could be thrown - this method must return null. It swallows Exception
s - which isn't nice and makes it hard to diagnose exactly which part of that code is failing. My money would be on this line - where canUseProvider()
可能 return false
。这一切都指向提供者 jar 由于某种原因无法访问。
我假设您在输出中没有看到任何访问冲突,即使 -Djava.security.debug=access,failure
也是如此。您可以尝试 -Djava.security.debug=all
,尽管这很可能只会产生更多不相关的日志记录。如果没有访问冲突,你 可能 在你的类路径上有两个版本的那个 jar 并且运行时正在访问(或试图访问一个错误)。 Q/A.
中描述了一个类似的案例
在面向客户的软件中,我们必须阅读给定的 URLs 来解析他们的内容。此外,客户需要激活 Tomcat-Security-Manager 以让 Java-Policies 控制程序的功能。
现在,读取 URLs 异常 "javax.net.ssl.SSLKeyException: RSA premaster secret error" 发生,但仅在特定条件下发生:
- 如果 URL 是 HTTPS 而不是 HTTP
- 如果安全管理器被激活,而不是在它被停用时或 如果在全局授权块中设置了 AllPermission
- 只有Java6,没有Java7(客户目前需要Java6)
- 只有Tomcat6,没有Tomcat7(客户目前需要Tomcat6)
安全违规发生在 Java-Code 的某处,限制在我们的代码库中的 AllPermission 并不能阻止错误。
所以,有没有人有想法,为Java 6 设置哪个权限,以便它可以处理HTTPS?
其他信息:运行 在 tomcat 中,在带有 OpenJDK 的 Debian-Linux 上。
编辑:我将 Java-Param“-Djava.security.debug=access,failure”添加到变量 JAVA_OPTS 中的 Tomcats /etc/default/tomcat6。但是在日志中我没有其他消息。代码可能会在触发之前询问权限吗?
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:到目前为止,我假设 Java-class URL 用于访问资源的内容。但这是不正确的。它使用来自 Grails-Code 的 Groovy-URL-object 和 getText()-method:
new URL(params.url).text
此行发生错误。它是 Grails 版本 2.2.4.
发现所有必需权限的简单方法是 运行 使用参数
-Djava.security.debug=access,failure
然后您将获得有关每次失败的安全访问、生效的保护域等的完整信息。
几条评论和 OP 确认解决方案(摘要)后的解决方案
根本原因是在多个位置存在 sunjce_provider.jar
。这是在被建议为许多可能的根本原因之一之后被 OP 发现的(请参阅此答案的最后和评论线索)。根据 OP 的评论:
I have the sunjce_provider.jar in multiple directories. I tried to give all three locations for Java 6 the rights, although clearly only one is JAVA_HOME - and it worked. Somehow one of the other locations is used, although it isn't in the java.ext.dirs-property
因此,本案例的解决方案是确保该应用有权访问 sunjce_provider.jar
我把我原来的回答的要点和有助于诊断的评论留在下面,供以后发现的人使用
导致解决方案的原始答案和评论
http
不会发生这种情况,因为您的 Web 应用程序(即此连接的客户端,即使它在 tomcat 中是 运行)不需要在此配置中生成密钥。它仅在启用 SecurityManager 时发生,但在禁用或使用全局 AllPermission 时不会发生,这表明它是文件权限错误。这表明这不是密钥长度的问题(例如 mentioned here)
其他 similar reports on the web 表示可能的根本原因是缺少 jar(通常引用 sunjce_provider.jar)。堆栈跟踪确认根本原因异常是 NoSuchAlgorithmException
,其中 KeyGenerator
正在寻找算法 SunTlsRsaPremasterSecret
但找不到它。在你的情况下,因为这只发生在特定的 SecurityManager
配置中,它可能是一个 inaccessible jar(由于安全权限) .
我的猜测是您没有启用对正确目录的 grant codeBase
权限,该目录包含您的 RSA 密钥生成算法所需的 jar。我建议的做法是检查您的 webapp 和 JRE 目录结构,以找到运行时 jar 的保存位置,并确保它们在 catalina.policy
.
grant
ed 权限
在默认配置中——例如——你应该在某处看到
// These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
permission java.security.AllPermission;
};
有关这意味着什么的详细信息,请参阅 tomcat 安全管理器“How To”的 this section。您需要检查一些事项 - 确保 ${java.home}/jre/lib/ext/
是您的运行时 jar 所在的位置。如果不是 - 更改路径以指向正确的位置(它 是 它们在我的 OpenJDK 6 版本 - build 27 上的位置。特别是你应该在那里看到 sunjce_provider.jar
和 sunpkcs11.jar
。确保以上部分存在于您的策略文件中。
代码可能取决于您的网络应用程序中的某些 jar - 例如在 ${catalina.base}/path/to/your/webapp/WEB-INF/classes/
中 - 在这种情况下,您需要授予对该目录的权限。
导致相同或相似症状的其他问题
App being unabled find or access
sunpkcs11.jar
也会报同样的错误信息(在Ubuntu+openjdk6+tomcat6系统上验证)。该 jar 的副本很可能也会。检查
/etc/java-6-openjdk/security/java.security
。它应该在那里列出提供者 - 检查那里是否有类似security.provider.n = sun.security.pkcs11.SunPKCS11
的行 - 如果缺少该行,你也会收到此错误(在同一系统上验证)这个Debian bug report讨论了运行在
下jar的位置问题SecurityManager
调试评论
根据其他答案,您可以尝试将 -Djava.security.debug=access,failure
添加到 CATALINA_OPTS
或 catalina.sh 中的 JAVA_OPTS
以启用调试 - 应记录到 catalina.out
默认情况下(或在 catalina.sh 中通过 CATALINA_OUT
设置日志记录的任何地方。您应该会看到 SecurityManager
的输出。
您也可以尝试 -Djava.security.debug=all. You will get a huge
catalina.out`,但您可以 grep 查找可能有帮助的词(例如“fail”!!!)
遵循堆栈跟踪中的代码
您的异常被抛出 here. Looking at how that exception could be thrown - this method must return null. It swallows Exception
s - which isn't nice and makes it hard to diagnose exactly which part of that code is failing. My money would be on this line - where canUseProvider()
可能 return false
。这一切都指向提供者 jar 由于某种原因无法访问。
我假设您在输出中没有看到任何访问冲突,即使 -Djava.security.debug=access,failure
也是如此。您可以尝试 -Djava.security.debug=all
,尽管这很可能只会产生更多不相关的日志记录。如果没有访问冲突,你 可能 在你的类路径上有两个版本的那个 jar 并且运行时正在访问(或试图访问一个错误)。 Q/A.