PHP 下载去除数字代码签名

PHP download removes digital code signature

我有一个 php 网络应用程序,允许我们的用户下载我们的软件安装程序 setup.exe

我们刚刚开始签署我们的代码,包括安装程序和其中的应用程序,一切都很好。但是,当我将此安装程序上传到我们的 Web 服务器并通过 php Web 应用程序下载它时,setup.exe 不再进行数字签名!就好像它一开始就没有签名一样。

这是我试过的方法:

  1. [right click] -> [properties] 表明 setup.exe 没有代码签名。然而 setup.exe 是预期的版本。
  2. 我运行安装程序,安装了我们的软件。安装的应用程序经过代码签名,并且预期版本与安装程序匹配。
  3. 我尝试通过 cpanel 文件管理器直接从 Web 服务器下载 setup.exe,这没问题 - setup.exe 已进行数字签名并且是预期的版本。
  4. 尝试通过不同的浏览器(firefox、edge)从网站下载 setup.exe 会导致相同的行为。

编辑

  1. 我也试过将 setup.exe 文件移动到站点的 public 区域,然后通过浏览器 直接 下载 - 完美运行。 我能想到的是,问题必须出在 PHP 如何将应用程序提供给浏览器。

我认为我们编写的 HTTP headers 或 PHP 下载功能可能与问题有关。

我们的通用 include.php 文件具有以下 headers 以防止缓存:

header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Fri, 01 Jan 2016 01:00:00 GMT");   // a date in the past

这是我们的下载功能:

function DownloadFile($file, $filename) {
    // check if file exists and write header info and output file
    if (file_exists($file)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/x-msdownload');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        readfile($file);
        return true;
    } 
    else { 
        // file does not exist
        return false; 
    }
}

主要来自readfile()example on php.net。这里有危险信号吗?怎么回事?

问题是由 Web 应用程序在 header 重定向到同一页面后提供文件的方式引起的 - 页面本身也提供其他数据作为内容。

调用 DownloadFile() 后,页面的其余部分(包括 HTML 内容等)作为文件的一部分发送 - 导致附加数据破坏了数字签名。

解决方案是在发送文件后强制脚本退出。

$file = $_SERVER['DOCUMENT_ROOT'] . '/../product/release/' . $path;
DownloadFile($file, "ProductInstaller.exe");
exit; // prevent the rest of the page from being sent as part of the file