【问题标题】:How do you programmatically sign jar files in Java?您如何以编程方式在 Java 中对 jar 文件进行签名?
【发布时间】:2021-03-08 13:03:45
【问题描述】:

以前有人做过吗?我在谷歌上找到的唯一参考是:http://onjava.com/onjava/2001/04/12/signing_jar.html,它仍然使用 sun.* 会导致问题的类...

也发现了这个,但不适用于 java16:https://svn.cs.cf.ac.uk/projects/whip/trunk/whip-core/src/main/java/org/whipplugin/data/bundle/JarSigner15.java

【问题讨论】:

  • 你可以从 java 中调用 jar 签名者进程。最好使用 ProcessBuilder。

标签: java jar sign


【解决方案1】:

为了解决 Java 7u45 中 WebStart 应用程序中安全限制的突然变化,我们创建了一个 simple signed jar file generator。它使用 Guava 15 和 Bouncy Castle bcpkix 模块。它应该在 Java 6 和 7 上运行。它只适用于小文件。将其用于您想要的任何目的。

【讨论】:

    【解决方案2】:

    请注意,sun.security.tools.JarSigner 类是为用作命令行实用程序而编写的,并非旨在从 Java 代码中调用。结果,错误处理非常突然:代码将简单地将错误消息打印到标准输出,然后调用System.exit()1

    这意味着,如果您从 Java 代码中调用该类并且在您尝试对 jar 签名时发生错误,则运行您的代码的 JVM 将简单地停止。根据您的情况,这可能没问题,但如果您的代码长时间运行或充当服务,那就不太好。

    因此,根据clamp 的注释,最好使用ProcessBuilder 调用jarsigner 工具。然后,您可以在生成的 Process 对象上调用 waitFor() 并检查 exitValue() 以查看命令是否成功。 getInputStream() 将让您在操作失败时读取写入标准输出的任何错误消息。

    【讨论】:

      【解决方案3】:

      在 tools.jar 文件中是 sun.security.tools.JarSigner 类,它有一个静态 run(ava.lang.String[] strings) 方法,它采用与 jarsigner 可执行文件相同的参数。

      所以你可以这样调用:

      sun.security.tools.JarSigner.run(new String[] {
          "-keystore", keystoreFile.getAbsolutePath(),
          "-storepass", keystorePassword,
          outFile.getAbsolutePath(),
          keystoreAlias 
      });
      

      您需要确保 tools.jar 在您的类路径中以便编译和执行。

      【讨论】:

        【解决方案4】:

        以下是使用 JDK 9 及更高版本执行此操作的方法:

        import java.io.*;
        import java.util.zip.*;
        import java.security.*;
        import jdk.security.jarsigner.*;
        
        char[] password = ...;
        String keyStorePath = ...;
        KeyStore ks = KeyStore.getInstance(new File(keyStorePath), password);
        KeyStore.ProtectionParameter protParam =
           new KeyStore.PasswordProtection(password);
        
        KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
           ks.getEntry("codecheck", protParam);
        
        JarSigner signer = new JarSigner.Builder(pkEntry)
           .build();
        String inputFile = ...;
        String outputFile = ...;
        try (ZipFile in = new ZipFile(inputFile);
              FileOutputStream out = new FileOutputStream(outputFile)) {
           signer.sign(in, out);
        }
        
        

        【讨论】:

          【解决方案5】:

          我正在使用SingJar Ant task(它显然调用了下面的命令行工具)。应该可以通过编程方式调用它。

          【讨论】:

          • @wuntee:如果可能的话,我怀疑 Ant taks 会这样做。
          猜你喜欢
          • 1970-01-01
          • 2011-09-05
          • 2017-02-07
          • 1970-01-01
          • 2011-05-11
          • 2013-06-12
          • 2013-01-29
          • 2019-12-24
          • 1970-01-01
          相关资源
          最近更新 更多