如何在 Java 中以编程方式对 jar 文件进行签名?

发布于 2024-12-08 19:50:49 字数 531 浏览 0 评论 0原文

以前有人这样做过吗?我在谷歌上找到的唯一参考是: https://web.archive .org/web/20150423130641/http://www.onjava.com/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

Has anyone done this before? The only reference I have found on google has been: https://web.archive.org/web/20150423130641/http://www.onjava.com/2001/04/12/signing_jar.html which still uses sun.* classes that will cause issues...

Found this as well, but does not work with java16: https://svn.cs.cf.ac.uk/projects/whip/trunk/whip-core/src/main/java/org/whipplugin/data/bundle/JarSigner15.java

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忆梦 2024-12-15 19:50:49

To address a sudden change of security restrictions in WebStart applications in Java 7u45 we have created a simple signed jar file generator. It uses Guava 15 and Bouncy Castle bcpkix module. It should run on Java 6 & 7. It is suitable for small files only. Use it for any purpose you want.

清风夜微凉 2024-12-15 19:50:49

以下是如何使用 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);
}

Here is how to do this with JDK 9 and beyond:

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);
}

淡看悲欢离合 2024-12-15 19:50:49

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

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

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

Be aware that the sun.security.tools.JarSigner class was written to be used as a command-line utility and wasn't designed to be called from Java code. As a result, the error handling is pretty abrupt: the code will simply print an error message to standard out and then call System.exit() 1.

This means that if you call the class from within your Java code and an error occurs when you try to sign a jar, the JVM running your code will simply stop. This may be fine depending on your situation, but if your code is long running or acting as a service, it's not so good.

It's therefore better to call the jarsigner tool using the ProcessBuilder as per clamp's comment. You can then call waitFor() on the resulting Process object and check exitValue() to see if the command was successful. getInputStream() will let you read any error messages that were written to standard out if the operation fails.

夜无邪 2024-12-15 19:50:49

在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位于你的类路径中以进行编译和执行。

In the tools.jar file is the class sun.security.tools.JarSigner which has a static run(ava.lang.String[] strings) method that takes the same parameters as the jarsigner executable does.

So you can call something like:

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

You need to make sure tools.jar is in your classpath for compiling and execution.

書生途 2024-12-15 19:50:49

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

I'm using the SingJar Ant task (which apparently calls the command line tool underneath). It should be possible to call that programmatically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文