我正在尝试解决签名 jar 在 appletviewer 下无法运行的问题。我的主要目标是在浏览器之外运行它,所以我尝试使用 appletviewer - 如果您有其他建议,请告诉我。
这是上下文:
- Ubuntu 11.10
爪哇:
$ java -version java version "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03) Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
这是问题所在:
- 我有一个罐子 myjar.jar 里面包含一个小程序
- 它在浏览器中正常工作,但在 appletviewer 下运行时不能
罐子签名:
$ jarsigner -verify -certs -verbose -keystore /etc/ssl/certs/java/cacerts myjar.jar ... smk <file size> <file date> <file name> X.509, CN=xxx, OU=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=xxx [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] X.509, CN=yyy, OU=yyy, OU=yyy, O=yyy, C=yyy [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] [KeyUsage extension does not support code signing] X.509, OU=zzz, O=zzz, C=zzz (alias1) [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] ... jar verified.
并且,虽然中间签名证书(上面的 yyy)不存在,但根证书(zzz - 或 alias1)是:
$ keytool -list -v -keystore /etc/ssl/certs/java/cacerts -storepass changeit|grep alias1
alias1, Mmm d, yyyy, trustedCertEntry,
运行这个:
$ appletviewer myhtml.html
给出:
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission preferences)
问题集 1:
- 是否假设存在根证书时,假设所有后续中间证书都可以用于验证目的?在上述情况下,是否有必要在 cacerts 文件中有 yyy ?
- 当 jar 被签名时,就像 myjar.jar 一样,是否假定 appletviewer 应该不受限制地运行?
- 有没有更好的方法来运行它来避免这种情况?
- 为什么这在浏览器中的工作方式与在 appletviewer 中的工作方式不同?
不确定以上内容,我尝试将证书添加到另一个名为 cacerts2 的本地文件中。我可以确认:
- keytool 在 cacerts 中列出该证书
jarsigner 输出现在是这样的:
$ jarsigner -verify -certs -verbose -keystore cacerts2 myjar.jar ... smk <file size> <file date> <file name> X.509, CN=xxx, OU=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=xxx [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] X.509, CN=yyy, OU=yyy, OU=yyy, O=yyy, C=yyy (alias2) [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] [KeyUsage extension does not support code signing] X.509, OU=zzz, O=zzz, C=zzz (alias1) [certificate is valid from m/d/y h:m PM to m/d/y h:m PM] ... jar verified.
请注意,现在我在输出中出现了中间别名(yyy - 或 alias2),并针对 alias1 和 alias2 进行了验证。像这样运行appletviewer:
$ appletviewer -J-Djavax.net.ssl.trustStore=cacerts2 -J-Djavax.net.ssl.trustStorePassword=changeit myhtml.html
仍然导致相同的异常。
问题集 2:
- 以上是提供信任库的正确方法吗?
- 以上是否意味着 appletviewer 将像 jarsigner 一样在传递 -keystore 命令进行验证时使用它?
我尝试的第三件事是制作这样的策略文件(在 mypolicy.policy 中):
keystore "cacerts2";
// Tried with this and without the next line:
//keystorePasswordURL "cacerts.pass";
// where file cacerts.pass has only "changeit" / "changeit\n" in it (tried both)
// Tried the following three:
grant signedBy "alias1" {
//grant signedBy "alias2" {
//grant {
permission java.lang.RuntimePermission "preferences";
};
并像这样运行:
$ appletviewer -J-Djava.security.policy=mypolicy.policy myhtml.html
像这样:
$ appletviewer -J-Djavax.net.ssl.trustStore=cacerts2 -J-Djavax.net.ssl.trustStorePassword=changeit -J-Djava.security.policy=mypolicy.policy myhtml.html
结果:
- 没有任何已签名规范的授权,所以我可以确认该政策已被采纳
- 使用任一signedBy 的授权失败
问题集 3:
- 这是指定策略和签名的正确方法吗?我发现Oracle提供的关于此主题的文档不完整
- 签署jar时甚至使用策略文件吗?
- 还有其他想法吗?:)