JarFile / ZipFile 缓存?
我需要验证我的应用程序中的签名 jar。我发现我可以通过阅读所有内容来做到这一点,如下所示:
public boolean verifyJar(String filePath) {
try {
JarFile jar = new JarFile(filePath, true);
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
InputStream is = jar.getInputStream(entry);
byte[] buffer = new byte[10000];
while (is.read(buffer, 0, buffer.length) != -1) {
// we just read. this will throw a SecurityException
// if a signature/digest check fails.
}
is.close();
}
return true;
} catch (Exception e) {
return false;
}
}
如果我使用有效的 jar 执行检查器,它就会通过。如果我把罐子切成两半而损坏了它,它就会失败。但是,如果我在一个进程中执行这两项操作,则第二次检查会通过(就好像它读取了文件的前一版本一样)!
public static void main(String[] args) throws Exception {
String path = "src/test/resources/temp/lib.jar";
// Passes - that's good
System.out.println(new Validator().verifyJar(path));
byte[] content = FileUtil.readFile(path);
FileUtil.save(path, Arrays.copyOf(content, content.length / 2));
// Passes - but it shouldn't.
// Fails if the first check is commented out though.
System.out.println(new Validator().verifyJar(path));
}
所以看起来 ZipFile
或 JarFile
是以某种方式缓存的。我该如何抑制这种行为?
I need to verify a signed jar from my application. I found I can do it by reading all contents, like this:
public boolean verifyJar(String filePath) {
try {
JarFile jar = new JarFile(filePath, true);
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
InputStream is = jar.getInputStream(entry);
byte[] buffer = new byte[10000];
while (is.read(buffer, 0, buffer.length) != -1) {
// we just read. this will throw a SecurityException
// if a signature/digest check fails.
}
is.close();
}
return true;
} catch (Exception e) {
return false;
}
}
If I execute the checker with a valid jar, it passes. If I corrupt the jar by cutting it in half, it fails. But if I do both in one process, the second check passes (as if it read the previous version of the file)!
public static void main(String[] args) throws Exception {
String path = "src/test/resources/temp/lib.jar";
// Passes - that's good
System.out.println(new Validator().verifyJar(path));
byte[] content = FileUtil.readFile(path);
FileUtil.save(path, Arrays.copyOf(content, content.length / 2));
// Passes - but it shouldn't.
// Fails if the first check is commented out though.
System.out.println(new Validator().verifyJar(path));
}
So it looks like ZipFile
or JarFile
is cached somehow. How do I suppress this behavior?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
必须关闭 ZipFile 才能使本机代码不缓存。如果路径和 File.lastModified 相同,则 Iirc ZipFile 会包装相同的句柄 (jzfile)。
或者,触摸 File.lastModified 也可以达到目的,但需要手动关闭任何打开的内容(包括 ZipFile)以防止资源泄漏。
ZipFile has to be closed in order native code not to cache. Iirc ZipFile wraps the same handle (jzfile) if the path and File.lastModified are the same.
Alternatively touching File.lastModified may do the trick too but closing anything open manually (incl. ZipFile) is necessary to prevent resource leaks.