PHP 下载去除数字代码签名
PHP download removes digital code signature
我有一个 php
网络应用程序,允许我们的用户下载我们的软件安装程序 setup.exe
。
我们刚刚开始签署我们的代码,包括安装程序和其中的应用程序,一切都很好。但是,当我将此安装程序上传到我们的 Web 服务器并通过 php
Web 应用程序下载它时,setup.exe
不再进行数字签名!就好像它一开始就没有签名一样。
这是我试过的方法:
[right click] -> [properties]
表明 setup.exe
没有代码签名。然而 setup.exe
是预期的版本。
- 我运行安装程序,安装了我们的软件。安装的应用程序经过代码签名,并且预期版本与安装程序匹配。
- 我尝试通过
cpanel
文件管理器直接从 Web 服务器下载 setup.exe
,这没问题 - setup.exe
已进行数字签名并且是预期的版本。
- 尝试通过不同的浏览器(firefox、edge)从网站下载
setup.exe
会导致相同的行为。
编辑
- 我也试过将
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
我有一个 php
网络应用程序,允许我们的用户下载我们的软件安装程序 setup.exe
。
我们刚刚开始签署我们的代码,包括安装程序和其中的应用程序,一切都很好。但是,当我将此安装程序上传到我们的 Web 服务器并通过 php
Web 应用程序下载它时,setup.exe
不再进行数字签名!就好像它一开始就没有签名一样。
这是我试过的方法:
[right click] -> [properties]
表明setup.exe
没有代码签名。然而setup.exe
是预期的版本。- 我运行安装程序,安装了我们的软件。安装的应用程序经过代码签名,并且预期版本与安装程序匹配。
- 我尝试通过
cpanel
文件管理器直接从 Web 服务器下载setup.exe
,这没问题 -setup.exe
已进行数字签名并且是预期的版本。 - 尝试通过不同的浏览器(firefox、edge)从网站下载
setup.exe
会导致相同的行为。
编辑
- 我也试过将
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