How to verify a jar signed with jarsigner programmatically

You can simply open the JAR with java.util.jar.JarFile and tell it to verify the JAR file. If the JAR is signed, then JarFile has the option to verify it (which is on by default). However, JarFile will also open unsigned JARs happily, therefore you must also check, whether or not the file is signed. You can do so by checking the JAR’s manifest for *-Digest attributes: Elements with such an attribute attribute are signed.

Example:

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

Leave a Comment