是什么阻止 Java 使用多种签名算法验证已签名的 jar

快速背景:我们发布了一个webstart应用程序,其中包括我们自己的应用程序jar和许多第三方jar。Webstart 要求 jnlp 文件引用的所有分布式 jar 都由单个证书签名。因此,我们使用自签名证书对所有 jar(我们的 jar 和第三方 jar)进行签名。一些第三方jar已经由产生它们的一方签名,但我们只是再次签名,这工作正常。直到现在。

问题:我们最近从Java 6迁移到Java 7,突然间webstart拒绝加载一些jar,抱怨:“无效的SHA1签名文件摘要”。这只发生在某些 jar 中,而不发生在其他 jar 中,并且公共线程出现在那些失败的 jar 中,似乎具有多个签名。

在S.O.和互联网上搜索后,Java的jarsigner的默认签名算法似乎在Java 6和Java 7之间发生了变化,从SHA1到SHA256,各种人都建议使用“jarsigner -digestalg SHA1”来解决验证问题。我试过了,果然,我们的多重签名罐子现在验证了。因此,这似乎是我们问题的解决方法。

据我所知,第三方签名似乎是SHA1签名,而我们使用默认值SHA256进行签名,从而导致签名混合。当我使用“-digestalg”开关强制SHA1时,我们有两个相同类型的签名,并且验证现在有效。所以问题似乎是由具有不同算法的多个签名引起的?还是我错过了其他一些因素。

问题:

  1. 为什么它无法使用 SHA1 + SHA256 进行验证,但使用 SHA1 + SHA1 进行验证?是否有技术原因?安全策略原因?为什么它不能验证两个签名是否正确?
  2. 我们使用(继续使用)SHA1而不是现在默认的SHA256有什么缺点吗?

答案 1

您可以为每个第三方签名者创建一个单独的 JNLP 文件,以引用相关的 jar 文件,然后让您的主 JNLP 依赖于这些元素,而不是自己对第三方 jar 进行重新签名。所有 JAR 文件必须由同一签名者签名的限制仅适用于一个 JNLP,每个扩展可以有不同的签名者。<extension>

如果做不到这一点,您可以在添加自己的签名之前剥离第三方签名(通过重新包装它们而无需META-INF/*.{SF,DSA,RSA})


答案 2

我知道这有点晚了 - 但我们现在要通过这个。我们的问题是“MD2withRSA”签名问题。我通过几个步骤解决了这个问题:

1) 与威瑞信合作,从我们的证书中删除“旧”算法 - 因此 MD2withRSA 算法不再用于对我们的 jar 进行签名。

2)我们还有一堆第三方罐子,我们只是用我们的证书重新签名。当SHA1和SHA-256算法都列在MANIFEST中时,我们遇到了“并非所有使用相同证书签名的jar”。断续器这只是jar的一小部分 - 所以对于那些,我们删除了MANIFEST的下半部分。MF 文件;具有 Name: 类和算法规范的部分。这些数据将在我们流程的最后一部分重新生成。我们解压缩,排除旧的签名信息并重新jar。最后一步是重新签署罐子。我们发现,在某些情况下,如果带有SHA1条目的旧名称:条目在清单中。MF,签名没有用SHA-256替换它 - 所以我们手动处理这些jar(现在)。正在努力更新我们的 Ant 任务来处理这个问题。

抱歉 - 无法解释为什么Web Start不处理/允许它 - 只是想出了如何使它工作!

祝你好运!


推荐