validationJar签名

我正在尝试以编程方式validationjar文件未被明显篡改。 我有2个用例我想阻止。 1)现有类的修改2)在jar中添加新类

我用jarsigner签了jar子。 当我用jarsignervalidation上述任何一种情况时,它就像我期望的那样工作。

当我尝试以编程方式使用如何validation以编程方式使用jarsigner 签名的jar或如何validation自签名jar上的签名时的示例? 但是,我没有获得任何SecurityExceptions …或任何例外情况。

不确定我做错了什么,因为这些片段似乎对其他人有用。 有任何想法吗? 这是JDK 1.6 BTW。

编辑:根据下面的要求,代码示例…提供您自己的修改jar 🙂

  JarFile myJar; try { //Insert the full path to the jar here String libPath = "" stature = new JarFile(libPath,true); //Don't really need this right now but was using it to inspect the SHA1 hashes InputStream is = myJar.getInputStream(myJar.getEntry("META-INF/MANIFEST.MF")); Manifest man = myJar.getManifest(); is.close(); verifyJar(myJar); } catch (IOException ioe) { throw new Exception("Cannot load jar file", ioe); } private void verifyJar(JarFile jar) throws Exception { Enumeration entries = jar.entries(); while (entries.hasMoreElements()) { java.util.jar.JarEntry entry = entries.nextElement(); try { jar.getInputStream(entry); //Also tried actually creating a variable from the stream in case it was discarding it before verification //InputStream is = jar.getInputStream(entry); //is.close(); } catch (SecurityException se) { /* Incorrect signature */ throw new Exception("Signature verification failed", se); } catch (IOException ioe) { throw new Exception("Cannot load jar file entry", ioe); } } } 

使用下面的示例,我获得了正确签名的JAR( true )和更改的JAR( false )的预期结果。 触发测试效果的一种简单方法是更改META-INF/MANIFEST.MF列出的一个摘要。

请注意,此方法忽略清单中列出的条目。 使用jarsigner -verify报告,“此jar包含未经过完整性检查的未签名条目。” 在完全读取流之后,可以使用entry.getCodeSigners()来确定条目是否具有任何签名者。

 import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** @see http://stackoverflow.com/questions/5587656 */ public class Verify { public static void main(String[] args) throws IOException { System.out.println(verify(new JarFile(args[0]))); } private static boolean verify(JarFile jar) throws IOException { Enumeration entries = jar.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); try { byte[] buffer = new byte[8192]; InputStream is = jar.getInputStream(entry); while ((is.read(buffer, 0, buffer.length)) != -1) { // We just read. This will throw a SecurityException // if a signature/digest check fails. } } catch (SecurityException se) { return false; } } return true; } } 

注意:对于JDK 8,仅仅获取输入流还不够。 与jarsigner ,也必须读取流。 在上面的代码中,在获得输入流之后添加了一个从jar signer 源改编的循环。

我弄清楚为什么会发生这种情况……这是一个愚蠢的错误。

我有我被篡改的签名jar,但我也编译了所有相同的类,因为这是我的开发环境。 因此,类加载器在jar类中选择了已编译的类。 编译的类没有清单,因此没有生成安全性错误。

删除已编译的类后,我得到了预期的安全性exception。