我正在尝试以编程方式验证jar文件未被明显篡改.我有2个用例我想阻止.1)现有类的修改2)在jar中添加新类
我用jarsigner签了罐子.当我用jarsigner验证上述任何一种情况时,它就像我期望的那样工作.
当我尝试以编程方式使用如何验证以编程方式使用jarsigner 签名的jar 或 如何验证自签名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<java.util.jar.JarEntry> 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用下面的示例,我获得了正确签名的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<JarEntry> 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;
}
}
Run Code Online (Sandbox Code Playgroud)
注意:对于JDK 8,仅仅获取输入流还不够.同样jarsigner,必须从中读取流.在上面的代码中,在获得输入流之后添加了从jar signer 源改编的循环.
我明白为什么这会发生在我身上......这是一个愚蠢的错误。
我有被篡改的签名 jar,但我也编译了所有相同的类,因为这是我的开发环境。因此,类加载器会选择已编译的类而不是 jar 类。编译的类没有清单,因此不会生成安全错误。
一旦我删除了编译的类,我就得到了预期的安全异常。
| 归档时间: |
|
| 查看次数: |
10437 次 |
| 最近记录: |