包格式

简介

应用程序管理器使用一个非常简单的包格式:一个标准的UNIX gzip压缩的TAR存档。元数据作为正常文件嵌入,但使用保留名称前缀--PACKAGE-。尽管USTAR tar存档支持很多特性,但应用程序管理器仅支持具有相对路径的标准文件和目录(路径中使用../不允许)。除了所有者的x位外,模式将被忽略。

这使得编写自定义打包器以及自定义app-store服务器后端变得非常容易,因为TAR存档处理可以作为任何编程语言的实用库使用。

注意:目前gzip是硬编码的,但由于压缩和解压缩是通过libarchive完成的,因此可以轻松替换为bzip2或xz压缩。这两种方法都会在Windows上导致额外的第三方依赖。

以下是一些重要的包文件

文件说明
--PACKAGE-HEADER--确切的一个YAML文档,必须是包中的第一个文件——下面将描述其格式。此文件用作格式选择器。
info.yaml应用程序的清单。打包工具需要确保此文件位于tar存档的前10个条目中。请参阅清单定义以了解文件格式的文档。
icon.png用于app-store的应用程序图标,也可以用作设备上启动菜单中的应用程序图标:请参阅info.yaml。打包工具需要确保此文件位于tar存档的前10个条目中。
--PACKAGE-FOOTER--一个或多个必须放在包最后一个文件(项)的YAML文档(项)——下面将描述其格式。如果需要添加多个页脚(例如,通过app-store服务器添加store签名),则可以在文件名中附加任意字符串(例如--PACKAGE-FOOTER--storesig)。这样做更容易对包进行故障排除,因为您可以使用标准的tar命令行工具轻松提取它们。

总之,以下是一些不允许在包中出现的项目

  • 不允许文件名以--PACKAGE-开头
  • 不允许使用绝对路径
  • 不允许在相对路径中使用../
  • 不允许有符号链接、硬链接、设备文件、套接字等。
  • 文件模式(除所有者的x位外)将被忽略。

校验和算法

所有包数据以及重要的元数据都通过SHA256摘要进行保护。这个校验和有两个用途:它能够保护数据传输过程中的错误,并且通过加密这个校验和来完成包的签名。

这个校验和的实际计算方法如下:

  • 对于不是--PACKAGE-*元数据文件的每一个文件,它的完整内容都会添加到摘要中。之后,以下UTF-8编码的字符串也会添加到摘要中:"F/<文件大小(字节>/<文件路径>"(例如,一个大小为250字节的foo/test.qml文件将生成F/250/foo/test.qml)。
  • 对于每一个目录,以下UTF-8编码的字符串会被添加到摘要中:"D/0/<目录路径>"(例如,foo/images目录将生成D/0/foo/images)。

生成的摘要会被放入--PACKAGE-FOOTER--中,作为一个32字节的十六进制编码字符串。

签名算法

当前包格式支持两种签名:开发者签名(在上传到appstore服务器之前由开发者生成)和商店签名(在客户端实际下载包之前由appstore服务器生成)。

这两种签名以相同的方式进行计算,并按相同的方式附加到包的元数据中:使用二进制摘要作为输入创建一个分离的PKCS7签名。然后,将这个PKCS7签名进行BASE64编码,并存储在--PACKAGE-FOOTER--字段中,无论是developerSignature还是storeSignature字段。

如果您想自己实现这个签名算法,请查看以下四个现有实现:

  • C++ OpenSSL,基于src/crypto-lib/signature_openssl.cpp
  • C++ WinCrypt,基于src/crypto-lib/signature_win.cpp(仅限Windows)
  • C++ SecurityFramework,基于src/crypto-lib/signature_macos.cpp(仅限macOS)
  • Python m2crypt,基于appstore服务器参考实现。

--PACKAGE-FOOTER----PACKAGE-HEADER--文件头部(第一个YAML文档)中的字段如下:

字段名称类型说明
formatVersionint必需。当前总是2
formatTypestring必需。对于头部始终是am-package-header,对于尾部始终是am-package-footer

--PACKAGE-FOOTER----PACKAGE-HEADER--数据(第二个YAML文档)中的字段如下:

字段名称类型说明
idstring包的唯一标识符。这必须与伴随的info.yaml清单文件中描述的包ID相匹配。
iconstring必需。图标的文件名。该文件必须位于与info.yaml相同的目录中,并且可以是Qt支持的任何图像格式。

注意:旧格式(5.14之前)将formatVersion头部字段设置为1,并且使用applicationId字段代替packageId字段。

示例包

这是一个最小QML应用程序包的示例。可以通过使用以下命令将这些文件压缩成tar文件来创建实际的包:

tar cvzf qmlapp.appkg ./--PACKAGE-HEADER-- info.yaml icon.png main.qml ./--PACKAGE-FOOTER--
文件内容
--PACKAGE-HEADER--
%YAML 1.1
---
formatType: am-package-header
formatVersion: 2
---
packageId: com.pelagicore.minimal
diskSpaceUsed: 1000
info.yaml
%YAML 1.1
---
formatType: am-package
formatVersion: 1
---
id: 'com.pelagicore.minimal'
icon: 'icon.png'
name:
  en: 'Minimal App'
applications:
- id: com.pelagicore.minimalapp
  code: 'main.qml'
  runtime: 'qml'
icon.png一个标准的png图像
main.qml您的QML应用程序
--PACKAGE-FOOTER--
%YAML 1.1
---
formatType: am-package-footer
formatVersion: 2
---
# SHA256 digest in 32 char hex representation
digest: '9df5635bb50e93846954c6377468c07835119e2835475ec90b3e9a9f7261cf27'

© 2024 The Qt Company Ltd。此处包含的文档贡献均为各自所有者的版权。所提供的文档根据由自由软件基金会发布的GNU自由文档许可证的1.3版条款许可。 Qt及其相关标志是The Qt Company Ltd.在芬兰及/或全球其他国家的商标。所有其他商标均为其各自所有者的财产。