Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,21 @@ dist/
build/
*.egg
.pytest_cache/
.test-tmp*/
.ruff_cache/
.venv-codex/
.mypy_cache/
.coverage
coverage.xml
htmlcov/

# 签名产物(证书、密钥、Profile、签名后的 hap)
signing_files/
signed_haps/
logs/
hapsign-config.json
output/
/*.hap

# 反编译参考源码(不参与运行,体积过大)
reverse/
Expand All @@ -25,6 +31,9 @@ reverse/
*.swp
*.swo

# 本地运行脚本(含个人环境变量,不提交)
run_sign_install.bat

# OS
Thumbs.db
Desktop.ini
Expand Down
57 changes: 56 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,64 @@
- Ruff、pytest、覆盖率、pre-commit 和 Windows CI 配置。
- 贡献指南、安全策略、行为准则和统一编辑器配置。
- CLI、缓存、HTTP 响应和权限提取的单元测试。
- 自动检测已签名 HAP:存在 Hap Signing Block 时跳过登录/申请/签名,直接安装。
- 签名块检测对齐 `developtools_hapsigner`(两阶段 EOCD、ZIP64 Locator、blockCount/尺寸边界)。
- PySide6 桌面界面,支持文件选择、HAP 拖放、后台执行和运行记录。
- 桌面版增加主动设备检测,并在签名安装前强制确认 HDC 设备可用。
- 运行记录使用统一的轻量滚动条样式,文件卡片支持移除误选 HAP。
- Windows 便携版声明 Per-Monitor V2 DPI 感知,并使用系统字体和小数缩放。
- 桌面版签名材料改为保存在程序目录的 `signing_files/`,便于随目录迁移。
- Windows 下 Java、keytool 和 HDC 使用无控制台窗口方式启动,消除闪窗。
- HDC server 采用“本次启动、本次关闭”策略,避免任务结束后遗留后台进程,
同时不终止 DevEco 等工具已有的 HDC 服务。
- PyInstaller 便携版构建配置,以及跨平台用户数据和工具链发现。
- 恢复 Playwright 受控浏览器作为默认登录环境,系统默认浏览器保留为备用模式。
- 新增 Playwright 受控系统 Edge/Chrome 模式并作为精简包默认值;兼容包仍可
携带内置 Chromium,普通系统默认浏览器只作为非受控备用。
- 桌面任务使用按实际阶段推进的百分比进度条,并支持主动取消。
- 执行中的登录、网络请求、Java/keytool、签名工具和 HDC 均响应取消信号;
关闭窗口时可确认中断,清理完成后自动退出。
- 新增程序目录 JSON 配置、滚动文件日志、日志级别和敏感诊断开关。
- 桌面设置可在程序目录、用户 AppData Local 和自定义签名目录之间切换,并可
一键打开签名目录或日志目录。
- 可选择是否保留签名后的 HAP;默认在程序目录 `signed_haps/` 中仅保留最新
一个,新文件发布成功后才删除旧文件,关闭后使用并清理任务临时文件。
- 便携构建采用带回退开关的保守精简:只排除已知无关的 JCEF/录像组件,并在
裁剪后强制执行 Chromium、Java、keytool 与 hap-sign-tool 自检。
- 设置页改为分区卡片布局,统一重绘下拉框、弹出菜单、复选框及操作按钮。
- Windows 字体改用整数逻辑像素、Microsoft YaHei UI 和完整 hinting,降低
150%/200% 高 DPI 下由分数物理像素造成的笔画发虚。
- 补充隐私说明、第三方组件声明和开源发布门禁;便携包构建会复制项目许可、
冻结依赖随附许可,并为本机复制的工具链生成 SHA-256 来源清单。
- 明确区分 MIT 源码发布与第三方二进制再分发:未确认具体 DevEco/SDK 版本许可前,
完整便携 ZIP 只用于本地构建验证。
- 正式 Windows 便携构建改用 `toolchain.lock.json` 锁定并校验的 OpenHarmony
6.1 公共 SDK 与 Eclipse Temurin 21;构建时仅提取 HDC、hap-sign-tool、
libusb 和 NOTICE,并以 `jlink` 生成精简 Java 运行时,同时随包保留来源、
哈希、许可材料及 libusb 对应源码。DevEco 工具链只保留为显式排障回退。
- 便携构建在 ZIP 旁自动生成标准 `.sha256` 校验文件,降低发布时手工抄录哈希出错的风险。

### Fixed

- HTTP 客户端正确发送 `User-Agent` / `Accept-Language` 请求头。
- Token 缓存缺少 `jwt_token` 时不再复用,避免后续刷新失败。
- 设备注册将业务层重复错误码视为成功,并保留 HTTP 错误信息中的兼容判定。
- 设备注册兼容服务端新增的 `205389858 (UDID is repeat)`,复用已注册设备,
不再把“设备已存在”当作安装失败。
- 签名工具默认密码统一引用 `HAPSIGN_KEYSTORE_PASSWORD` / 配置默认值。
- 登录回调兼容根路径、`/callback` 及其他本地路径上的 GET/POST 回调,
并支持普通表单、multipart 表单、JSON、查询参数和 CORS 预检,修复授权后
一直等待的问题;用户拒绝授权时也会立即结束等待。
- 登录回调支持 Chromium Private Network Access 预检、缺失 multipart 类型推断
及嵌套 JSON;运行记录会显示不含 token 的回调方法、类型和字段诊断信息。
- 已选 HAP 卡片固定显示在拖放区右侧,避免窗口布局变化时覆盖拖放区。
- 主动取消任务后将进度条重置为 0%。
- 登录成功响应恢复为已验证实现使用的 DevEco 成功页跳转,并为受控 Chromium
预授予本地网络访问权限,避免授权完成后回调请求被浏览器策略拦截。

### Security

- 登录回调服务仅监听 loopback 地址。
- 登录日志不再包含 token、请求体、CSRF code、用户 ID、设备 UDID 或完整登录 URL。
- 日志默认不包含 token、完整请求体、CSRF code 或完整登录 URL;只有用户主动开启
“敏感诊断”且使用 DEBUG 级别时才记录完整网络载荷,密钥库密码始终排除。
- 限制登录回调请求体大小,并尽力收紧 token 缓存文件权限。
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,19 @@ python -m pytest --cov
也可以安装 `pre-commit` 后运行 `pre-commit install`。仓库中的本地 hooks 使用当前
Python 环境已安装的 Ruff,不会在执行时下载额外工具。

## 桌面版与打包

修改 GUI、运行时发现或打包配置后,除单元测试外还应构建一次当前平台的
PyInstaller 便携版,并运行打包后的 `--smoke-test`。完整步骤、工具链要求和
发布检查清单见 [docs/PACKAGING.md](docs/PACKAGING.md)。

## Pull request

- 每个 PR 聚焦一个问题,并说明行为变化和验证方式。
- 新增或修复逻辑时补充不依赖真实账号、网络和设备的测试。
- 不在测试中调用真实华为服务;使用 pytest 的 monkeypatch 或 mock。
- 若改动用户可见行为,在 `CHANGELOG.md` 的 Unreleased 小节记录。
- API 来自非公开实现时,应在说明中标注兼容性风险,不提交第三方反编译产物。
- 新增运行时依赖或便携包二进制时,同步更新 `THIRD_PARTY_NOTICES.md`,并提供
可审计的来源、版本、哈希和再分发许可。
- 完整便携包的公开发布还必须通过 `docs/OPEN_SOURCE_RELEASE.md` 的许可与隐私门禁。
93 changes: 93 additions & 0 deletions PORTABLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# HapSign 便携版

解压 ZIP 后双击 `HapSign.exe`(macOS/Linux 使用对应平台可执行文件)。

## 使用方法

1. 用 USB 连接 HarmonyOS 设备,并确认设备已允许调试。
2. 可点击“检测设备”确认设备已连接并授权;也可以直接开始,程序会自动检测。
3. 将 `.hap` 文件拖入窗口,或点击选择文件;误选时点击文件右侧的“×”移除。
4. 点击“开始签名并安装”。
5. 如果 HAP 尚未签名,程序会控制系统 Edge(其次 Chrome)打开华为登录页;
完成登录后程序会继续。

进度条按当前实际流程阶段推进。任务执行期间可以点击“取消”;如果直接关闭窗口,
程序会询问是否中断当前任务。确认后会先结束登录等待或外部工具、清理本次启动的
HDC 服务,再退出。取消不会复用未完成任务的运行状态,可直接重新开始。

签名后的 HAP、证书、Profile、密钥库和登录令牌默认保存在程序目录下:

```text
HapSign/
├── HapSign.exe
├── signing_files/
├── .token_cache.json
└── <bundle_name>/
└── signed_haps/ # 最新一个签名 HAP
```

请把便携版解压到当前用户可写的目录,不要放进 `Program Files` 等受保护位置。
移动整个 `HapSign` 目录时,签名材料和缓存会一起移动。

标题栏的“设置”可把签名目录改为当前用户的 `AppData Local` 或自定义目录,也可
直接打开签名目录和日志目录。配置文件是程序目录下的 `hapsign-config.json`;
日志默认写入 `logs/hapsign.log`,无法写入程序目录时会回退到用户本地数据目录。
敏感日志默认关闭;只有主动开启且日志级别为 DEBUG 时才记录 token、用户标识及
完整 API 请求/响应。签名库密码始终不会写入日志。

“保留最新一个签名后的 HAP”默认开启。程序会在新 HAP 完整签名成功后写入
`signed_haps/`,只删除 HapSign 清单记录的旧产物,因此不会误删目录中的用户 HAP,
当前输入文件也不会被清理,签名失败也不会破坏上一份。关闭该开关后,签名 HAP 只
作为安装临时文件,任务结束后自动清理。

输入已签名 HAP 时会直接安装,不产生新的签名材料。
Java、keytool 和 HDC 等外部命令会在后台执行,不会弹出命令行窗口。
任务结束时只关闭由本次任务启动的 HDC server;原本由 DevEco 等工具启动的
既有 HDC server 不会被终止。

## 构建

构建机需要 Python 3.11+。目标电脑不需要安装 Python 或 DevEco Studio;默认
精简包要求目标 Windows 已安装 Edge 或 Chrome。正式 Windows 构建先准备锁定的
OpenHarmony/Temurin 工具链:

```bash
python -m pip install -e ".[gui,bundle]"
python scripts/prepare_toolchain.py
python scripts/build_portable.py
```

要生成不依赖系统浏览器二进制的兼容包:

```powershell
$env:PLAYWRIGHT_BROWSERS_PATH = "0"
python -m playwright install --no-shell chromium
python scripts/build_portable.py --keep-bundled-browser
```

构建结果位于 `dist/HapSign-portable-<platform>.zip`,同目录会生成可用于发布校验的
`.zip.sha256` 文件。
兼容包位于 `dist/HapSign-portable-<platform>-compat.zip`。
准备脚本使用 `jlink` 生成精简 Temurin 运行时,构建脚本会自动执行 Java、
keytool、hap-sign-tool、HDC 和冻结程序自检。

仅调试 GUI、不复制外部工具链时可以运行:

```bash
python scripts/build_portable.py --skip-toolchain
```

该 GUI-only 包不能在没有外部工具链的电脑上完成签名和安装。完整的构建环境、
资源发现顺序、目录结构、验证方法和发布清单见 `docs/PACKAGING.md`;生成的便携
目录中也会包含一份 `BUILDING.md`。

PyInstaller 产物与当前操作系统绑定,因此 Windows、macOS、Linux 需要分别构建。
锁文件会记录公共 SDK、Temurin 和核心文件哈希;发布包也包含生成时的
`PROVENANCE.txt`、完整 OpenHarmony NOTICE、Temurin legal 目录,以及
`libusb_shared.dll` 对应的 OpenHarmony 源码快照。若使用
`--allow-deveco-toolchain` 回退,本次产物只用于本机排障,不得公开发布。

发布包根目录会包含 HapSign 的 `LICENSE`、`PRIVACY.md`、
`THIRD_PARTY_NOTICES.md` 和 `BUILDING.md`,冻结依赖随附的许可文件位于
`licenses/python/`。Temurin legal、OpenHarmony NOTICE 和 libusb 对应源码也必须
保留。
48 changes: 48 additions & 0 deletions PRIVACY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Privacy and local data

HapSign 是本地运行的开源工具,项目维护者没有自建后端、遥测、广告或崩溃上报。
但签名流程需要用户主动登录华为开发者服务,并直接与华为域名通信。使用这些服务时,
数据处理还受华为账号、开发者服务及所在地区适用条款约束。

## 网络通信

程序只在用户启动签名流程后访问:

- `https://devecostudio.huawei.com`:登录、临时令牌和访问令牌交换;
- `https://connect-api.cloud.huawei.com`:团队、证书、设备、应用和 Provision
Profile 管理;
- 上述服务返回的短期证书/Profile 下载地址;
- `127.0.0.1` 的临时回调端口:浏览器把登录结果交还给本机 HapSign,不对局域网
或公网监听。

发送给华为服务的数据可能包括账号令牌、用户和团队标识、CSR 公钥请求、证书名称、
HAP 包名、HAP 声明的待预授权权限、设备 UDID/类型/自动生成的设备名、证书 ID、
设备 ID、应用 ID 以及 Profile 名称。HAP 文件正文、私钥和密钥库密码不会上传;
HAP 签名在本机完成。

程序会查询、创建和在必要时删除当前账号下的调试证书、设备记录及 Provision
Profile。重复 UDID 会复用已有设备记录。用户应确认自己有权对相应账号、应用和设备
执行这些操作。

## 本地保存

根据设置,以下文件保存在程序目录、用户 Local AppData 或用户选择的目录:

- `signing_files/.token_cache.json`:访问令牌、刷新令牌、JWT 和账号基本字段;
- `signing_files/<bundle>/`:私钥密钥库、CSR、证书、Profile 和缓存元数据;
- `signed_haps/`:可选保留的最后一个已签名 HAP;
- `logs/hapsign.log*`:诊断日志;
- `hapsign-config.json`:日志级别、保存位置和功能开关。

令牌和签名材料按日期复用,但不会由项目维护者远程删除。用户可关闭应用后删除上述
目录;分享、卸载或移动便携目录前也应主动检查。签名 HAP 可能包含用户自有代码,不应
随公开问题报告或发布包上传。

## 日志

默认日志不会记录 token、完整登录 URL、完整回调正文或完整 API 请求/响应。只有用户
同时选择 DEBUG 级别并开启“记录敏感诊断信息”后,日志才可能包含这些内容;密钥库密码
始终不记录。敏感排障完成后应关闭开关并删除已有日志与令牌缓存。

更多安全建议见 [SECURITY.md](SECURITY.md)。源代码可以审计全部网络端点;如果不接受
上述数据流,请不要启动登录和签名流程。
Loading
Loading