如何以编程方式在Java中对jar文件进行签名?
以前有人这样做过吗?我在google上找到的唯一参考资料是:它仍然使用sun.*类,这将导致问题如何以编程方式在Java中对jar文件进行签名?,java,jar,sign,Java,Jar,Sign,以前有人这样做过吗?我在google上找到的唯一参考资料是:它仍然使用sun.*类,这将导致问题 也发现了这一点,但不适用于java16:我正在使用(它显然调用下面的命令行工具)。应该可以通过编程方式调用它。tools.jar文件中的类是sun.security.tools.JarSigner,它有一个静态run(ava.lang.String[]strings)方法,该方法采用与JarSigner可执行文件相同的参数 所以你可以称之为: sun.security.tools.JarSigner
也发现了这一点,但不适用于java16:我正在使用(它显然调用下面的命令行工具)。应该可以通过编程方式调用它。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位于类路径中以进行编译和执行。为了解决Java 7u45中WebStart应用程序中安全限制的突然变化,我们创建了一个。它使用番石榴15和Bouncy Castle bcpkix模块。它应该在Java6和Java7上运行。它只适用于小文件。可以将其用于任何目的。请注意,
sun.security.tools.JarSigner
类是作为命令行实用程序编写的,而不是从Java代码调用的。因此,错误处理非常突然:代码只需将错误消息打印到标准输出,然后调用System.exit()
这意味着,如果您从Java代码中调用该类,并且在尝试对jar进行签名时出现错误,那么运行代码的JVM将简单地停止。根据您的情况,这可能很好,但如果您的代码长时间运行或充当服务,那么就不太好了
因此,根据clamp的评论,最好使用ProcessBuilder调用jarsigner工具。然后,您可以对生成的流程对象调用
waitFor()
,并检查exitValue()
以查看该命令是否成功<如果操作失败,code>getInputStream()将允许您读取写入标准输出的任何错误消息。以下是如何使用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);
}
您可以从java内部调用jar签名者进程。最好使用ProcessBuilder。@wuntee:我怀疑Ant-Tak会很容易做到这一点。