在针对客户的软件中,我们必须阅读给定的URL来解析其内容。客户还需要激活Tomcat-Security-Manager,让Java-Policies控制程序的功能。
现在,通过读取URL,发生异常“javax.net.ssl.SSLKeyException:RSA premaster secret error”,但仅在某些条件下:
安全违规发生在Java代码的某处,限制在我们的代码库中的AllPermission不会阻止错误。
那么,是否有人有想法,为Java 6设置哪个权限,以便它可以处理HTTPS?
其他信息:它在一个tomcat中运行,在带有OpenJDK的Debian-Linux上运行。
编辑:我在变量JAVA_OPTS中向Tomcats / etc / default / tomcat6添加了Java-Param“-Djava.security.debug = access,failure”。但在日志中我没有其他消息。代码可能会在触发它们之前询问权限吗?EDIT2:我找到了正确的位置并获得了完整的堆栈跟踪(删除了特定的客户部分):
new URL(params.url).text
EDIT3:到目前为止,我假设使用Java类URL来访问资源的内容。但这是不真实的。它使用Grails-Code将Groovy-URL-object与getText()方法一起使用:
function showdivs() { //this is called, when you click a link
var divs = $("#info,#add_new");
//Show chosen div, and hide all others
$("li a").click(function() {// here the clickhandler is added, so the first time it won't work
$(divs).hide();
$("#" + $(this).attr("class")).show();
});
错误发生在这一行。这是Grails-version 2.2.4。
答案 0 :(得分:8)
发现所有必需权限的简便方法是使用参数
运行-Djava.security.debug=access,failure
然后,您将获得有关每个失败的安全访问,有效保护域等的完整信息。
答案 1 :(得分:8)
根本原因是在多个位置存在sunjce_provider.jar
。这被OP发现后被认为是许多可能的根本原因之一(参见本答案的最后部分和评论记录)。根据OP的评论:
我在多个目录中有sunjce_provider.jar。我试图给Java 6的所有三个位置提供权限,虽然显然只有一个是JAVA_HOME - 并且它有效。不知何故使用了其他位置之一,尽管它不在java.ext.dirs-property
中
因此,本案的解决方案是确保应用有权访问sunjce_provider.jar
的正确副本
我已经从我原来的答案中留下了主要观点以及有助于诊断的评论,以供稍后发现的人使用
http
不会发生这种情况,因为您的网络应用(即此连接的客户端,即使它在tomcat中运行),也不需要在此生成密钥配置。
事实上它只在启用SecurityManager时发生,但如果禁用或全局AllPermission则表明其文件权限错误。它表明密钥长度不是问题(例如mentioned here)
其他similar报告on web表示可能的根本原因是缺少jar(通常引用sunjce_provider.jar)。堆栈跟踪确认根本原因异常是NoSuchAlgorithmException
KeyGenerator
正在寻找算法SunTlsRsaPremasterSecret
并且无法找到它。在您的情况下,因为这只发生在特定的SecurityManager
配置中,它可能是 无法访问的 jar(由于安全权限)。
我的猜测是你没有对包含RSA keygen算法所需jar的正确目录启用grant codeBase
权限。我建议的做法是通过您的webapp和JRE目录结构来查找保留运行时jar的位置,并确保它们在grant
中具有catalina.policy
个权限。
在默认配置中 - 例如 - 你应该看到某个地方
// These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
permission java.security.AllPermission;
};
有关详细信息,请参阅tomcat安全管理器的this section"如何"。您需要检查一些事项 - 确保${java.home}/jre/lib/ext/
是运行时罐子的位置。如果不是 - 改变指向正确位置的路径( ,它们位于我的OpenJDK 6版本 - 构建27)。特别要在那里看到sunjce_provider.jar
和sunpkcs11.jar
。确保您的政策文件中存在上述部分。
可能是代码依赖于您的webapp中的一些jar - 例如在${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 bug report讨论了在SecurityManager
根据其他答案,您可以尝试在catalina.sh中将-Djava.security.debug=access,failure
添加到CATALINA_OPTS
或JAVA_OPTS
以启用调试 - 默认情况下应记录到catalina.out
(或者您在catalina.sh中通过CATALINA_OUT
设置日志记录的位置。您应该看到SecurityManager
的输出。
你也可以试试-Djava.security.debug=all. You will get a huge
catalina.out`,但你可以找一些可能有帮助的词(比如"失败" !!!)
您的异常被抛出here。看看如何抛出异常 - this method必须返回null。它swallows Exception
s - 这并不好,并且很难准确诊断该代码的哪个部分失败。我的钱将在this line - canUseProvider()
可能会返回false
。这一切都指向提供者jar由于某种原因无法访问。
我假设您在输出中没有看到任何访问冲突,即使使用-Djava.security.debug=access,failure
也是如此。您可以尝试-Djava.security.debug=all
,尽管这可能只会产生更多不相关的日志记录。如果没有访问冲突, 可能 在您的类路径上以某种方式具有该jar的两个版本,并且运行时正在访问(或尝试访问错误的jar)。此Q/A中描述了与此类似的案例。