Java 下载程序从已签名的 exe 中删除数字证书

Java downloader removes digital certificate from signed exe

我正在开发 java 下载器,它可以从远程服务器拉取文件并保存在本地。

这是我使用的代码:

try {

    BufferedInputStream in = new java.io.BufferedInputStream(new URL(link).openStream());
    FileOutputStream fos = new FileOutputStream(destination);
    BufferedOutputStream bout = new BufferedOutputStream(fos,1024);

    byte data[] = new byte[1024];
    int count;

        while( (count = in.read(data,0,1024)) != -1){
        bout.write(data,0,count);
        }

    fos.flush();
    fos.close();
    fos.close();


    } catch(Throwable t){
    t.printStackTrace();
} 

我注意到的第一件事是,服务器上的文件和下载的文件大小不完全相同 --> http://puu.sh/jGpEj/abbe832796.png(下载的文件小几个字节)。请注意 "size on the disk" 看起来是一样的。

接下来我注意到,如果我尝试 运行 java "as administrator" 下载的 .exe,它会说 "Publisher: Unknown" 这是不正确的,因为 .exe 是数字化的签。 "Digital Signatures" 选项卡都不存在。

任何线索可能是什么问题?

P.S 我用十六进制编辑器打开了这两个文件..它们似乎都有相同的内容,除了 java 下载的文件缺少最后 94 个字节。

您正在写入 BufferedOutputStream,但您正在刷新下游流之一。换句话说,您在错误的流上调用 flush()

改为刷新 BufferedOutputStream bout

try {
  BufferedInputStream in = new java.io.BufferedInputStream(new URL(link).openStream());
  FileOutputStream fos = new FileOutputStream(destination);
  BufferedOutputStream bout = new BufferedOutputStream(fos,1024);

  byte data[] = new byte[1024];
  int count;

  while( (count = in.read(data,0,1024)) != -1){
    bout.write(data,0,count);
  }

  bout.flush();
  bout.close();

  in.close();

} catch(Throwable t){
  t.printStackTrace();
} 

您还应该 close BufferedOutputStream,它会自动传播关闭底层流。换句话说,你不直接关闭FileOutputStream

最后,实际上没有必要在 close() 之前调用 flush(),因为执行 close() 无论如何都会自动执行 flush()

顺便说一句,如果您使用 try-with-resources 块,您可以让编译器为您插入关闭。