如何验证与编程签署的jarsigner一罐(How to verify a jar signed w

2019-06-21 16:51发布

我想使用的jarsigner签署一个罐子,然后使用不具有签名的jar作为它的一部分的类路径中的Java应用程序验证(即只使用的jar文件系统位置)

现在我的问题越来越签名文件出了罐子,有一个简单的方法来做到这一点?

我已经受够了,没有运气充气和罐InputStreams一出戏。

或者是这个东西,可以以更好的方式来完成?

谢谢

Answer 1:

在安全提供者实施指南列出了验证JAR文件的过程。 虽然这些指令是一个JCA的加密服务提供程序来验证本身,就应该适用于您的问题。

具体而言,检查了verify(X509Certificate targetCert)中的示例代码,方法“MyJCE.java” 。



Answer 2:

你可以简单地打开与java.util.jar.JarFile中的JAR,并告诉它来验证JAR文件。 如果JAR进行签名,然后jar文件必须验证它(这是在默认情况下)的选项。 然而,jar文件也将愉快地打开未签名的JAR文件,因此,你还必须检查,该文件是否被签名。 具有这样的属性属性的元素都签署:您可以通过检查JAR的清单为* -Digest属性这么做。

例:

JarFile jar = new JarFile(new File("path/to/your/jar-file"));

// This call will throw a java.lang.SecurityException if someone has tampered
// with the signature of _any_ element of the JAR file.
// Alas, it will proceed without a problem if the JAR file is not signed at all
InputStream is = jar.getInputStream(jar.getEntry("META-INF/MANIFEST.MF"));
Manifest man = new Manifest(is);
is.close();

Set<String> signed = new HashSet();
for(Map.Entry<String, Attributes> entry: man.getEntries().entrySet()) {
    for(Object attrkey: entry.getValue().keySet()) {
        if (attrkey instanceof Attributes.Name && 
           ((Attributes.Name)attrkey).toString().indexOf("-Digest") != -1)
            signed.add(entry.getKey());
    }
}

Set<String> entries = new HashSet<String>();
for(Enumeration<JarEntry> entry = jar.entries(); entry.hasMoreElements(); ) {
    JarEntry je = entry.nextElement();
    if (!je.isDirectory())
        entries.add(je.getName());
}

// contains all entries in the Manifest that are not signed.
// Ususally, this contains:
//  * MANIFEST.MF itself
//  * *.SF files containing the signature of MANIFEST.MF
//  * *.DSA files containing public keys of the signer

Set<String> unsigned = new HashSet<String>(entries);
unsigned.removeAll(signed);

// contains all the entries with a signature that are not present in the JAR
Set<String> missing = new HashSet<String>(signed);
missing.removeAll(entries);


Answer 3:

您可以使用entry.getCodeSigners()来获得签名者在JAR中的特定条目。

确保打开jar文件与核实=真实和充分阅读调用entry.getCodeSigners前的JAR条目()。

像这样的东西可以用来验证是不是一个签名文件的每个条目:

boolean verify = true;
JarFile jar = new JarFile(signedFile, verify);

// Need each entry so that future calls to entry.getCodeSigners will return anything
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
   JarEntry entry = entries.nextElement();
   IOUtils.copy(jar.getInputStream(entry), new NullOutputStream());
}

// Now check each entry that is not a signature file
entries = jar.entries();
while (entries.hasMoreElements()) {
    JarEntry entry = entries.nextElement();
    String fileName = entry.getName().toUpperCase(Locale.ENGLISH);
    if (!fileName.endsWith(".SF")
       && !fileName.endsWith(".DSA")
       && !fileName.endsWith(".EC")
       && !fileName.endsWith(".RSA")) {

       // Now get code signers, inspect certificates etc here...
       // entry.getCodeSigners();
    }
 }


Answer 4:

您可以使用的jarsigner应用程序来做到这一点。 在的ProcessBuilder(或的Runtime.exec),您可以运行这些参数的命令

 ProcessBulider pb = new ProcessBuilder("/usr/bin/jarsigner", "-verify", "-certs", f.getAbsolutePath());

而如果证实输出,则为然后将罐子签署

Process p = pb.start();
p.waitFor();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
{
if(line.contains("verified");
...

还有更复杂的东西,当你拥有的jarsigner代码的输出,你可以做。



文章来源: How to verify a jar signed with jarsigner programmatically