docs(harmony): ★★ 推送根因定位到"**签错了证书**",不是"debug 证书不被接受"
平板复测抓到一条上一轮漏掉的华为侧日志,它把根因从推断变成实测:
E cloudinterfaceauth/AuthService: cert finger empty, clientId: 2039846327155747840
I PushService: push token 取不到:code=1000900010 Illegal application identity
★ `cert finger empty` = 设备报上来的是**空指纹**,不是"指纹对不上"。
与 `bm dump` 完全吻合:appSignType=none、signatureKey=""。
⇒ 包里根本没有应用签名身份。
三个指纹实测对比(本机 openssl 算出):
build-profile.json5 的 certpath → DF:21:A3:C0:…:DF:3A:37 CN=Huawei CBG Root CA G2
.p7b 内嵌 development-cert → FD:89:AC:53:…:FC:9D:09 CN=靳睿(…)\,Development
⇒ 工程签的是 **CA 根证书**,profile 绑的是**开发者应用证书**,两者根本不是同一张。
profile 侧其余要素已逐项排除为无关:bundle-name 对、type=debug、validity 未过期、
平板 UDID(bm get -u)逐字出现在 device-ids 里。
★★ 顺带记下走不通的那条路,免得下次重走:
把 certpath 改成 profile 内嵌的单张 dev cert → hvigor 报
`11013004 Profile cert must a cert chain`。
**certpath 要的是一条链**,而那张 dev cert 的签发者
`Huawei CBG Developer Relations CA G2` 本机没有(5 个 p7b 里都没有,
material/ 里也没有任何证书)。
⇒ 给用户要材料时要说准:要**能构成链的整套**,单张 .cer 装不上;
最省事是 DevEco 里 Project Structure → Signing Configs 直接同步签名。
服务端侧本轮复验仍正常:与 hms.go 同形(不带 scope)请求华为换到
access_token,长度 104、有效期 3600s ⇒ 断点确实只在设备侧签名。
build-profile.json5 的 certpath 保持原值并加了注释:改成单张 dev cert 会编译不过,
留着编不过的值只会连应用都装不上。
This commit is contained in:
@ -5,6 +5,30 @@
|
||||
name: 'default',
|
||||
type: 'HarmonyOS',
|
||||
material: {
|
||||
/*
|
||||
* ★★ 2026-10-02 真机推送排查:**这里签的是 CA 根证书,不是应用证书**。
|
||||
*
|
||||
* 设备实测(平板 MRDI-W00,`bm dump`):
|
||||
* "appSignType": "none" / "signatureKey": "" / "appProvisionType": "debug"
|
||||
* ⇒ 包里**根本没有应用签名身份**,于是 HMS 的
|
||||
* `AuthService: cert finger empty, clientId: 2039846327155747840`
|
||||
* 拿不到指纹,判成 `1000900010 Illegal application identity`,
|
||||
* push token 因此永远取不到(`push_tokens` 表 0 行)。
|
||||
*
|
||||
* 证书比对(本机实测的三个指纹):
|
||||
* 本文件这个 .cer DF:21:A3:C0:…:DF:3A:37 CN=Huawei CBG Root CA G2 ← CA 根
|
||||
* profile 内嵌 dev cert FD:89:AC:53:…:FC:9D:09 CN=靳睿(…)\,Development ← 应用的
|
||||
* profile 的 type "debug"
|
||||
* ⇒ 签的证书与 profile 绑定的**不是同一张**,这就是 "cert finger empty" 的来源。
|
||||
*
|
||||
* ⚠️ 曾把它改成 profile 内嵌的单张 dev cert 想试,hvigor 直接报
|
||||
* `11013004 Profile cert must a cert chain` —— **certpath 要的是一条链**
|
||||
* (应用证书 + 签发它的 CA),而 dev cert 的签发者
|
||||
* `Huawei CBG Developer Relations CA G2` **本机没有**(5 个 p7b 里都没有)。
|
||||
* ⇒ 要修好必须补齐 dev cert 的**签发链**(AGC/DevEco 后台导出的那套发布或调试证书),
|
||||
* 然后把 certpath 指向那条链。在那之前这里保持原样,
|
||||
* 因为改成一个编译不过的值只会连应用都装不上。
|
||||
*/
|
||||
certpath: '/root/.ohos/config/default_harmony_k2yruKTLaTiZOjublhUDTfveVx5uFoHqm96pwkUw=.cer',
|
||||
keyAlias: 'debugKey',
|
||||
keyPassword: '0000001b64d7bb074eed97bb2c6ad5ae60df2f72256b104361c3fd8c4f842eb42961fce4b712e7410dd208',
|
||||
|
||||
178
docs/PUSH-DEVICE-DIAGNOSIS.md
Normal file
178
docs/PUSH-DEVICE-DIAGNOSIS.md
Normal file
@ -0,0 +1,178 @@
|
||||
# 真机推送联合调试:诊断报告
|
||||
|
||||
日期:2026-10-01
|
||||
设备:HUAWEI MatePad Pro(MRDI-W00),HarmonyOS NEXT,`const.ohos.apiversion = 26`
|
||||
连接:`hdc tconn 192.168.2.87:43679`
|
||||
应用:`com.jianf.agentmail`(设备上已装、已登录 `jianf`、SSE 已连通)
|
||||
|
||||
---
|
||||
|
||||
## 一 结论先说
|
||||
|
||||
**推送链路的每一段都正常,唯一断点是「平板取不到 HMS token」,而它与证书绑定有关。**
|
||||
|
||||
已实测排除:
|
||||
|
||||
| 环节 | 状态 | 证据 |
|
||||
|---|---|---|
|
||||
| 拓扑(平板 → 网关) | ✓ 通 | `mail.jianfgit.xyz` = 192.168.2.60 = 本机;设备 SSE 已 connected |
|
||||
| 应用本身 | ✓ 正常 | 登录态在、收件箱渲染、SSE 收流 |
|
||||
| HMS Core | ✓ 在 | `com.huawei.hms.pushservice` + `accountmgr` + `hms.pafservice` 均运行 |
|
||||
| 服务端 HMS 凭证 | ✓ 有效 | 向华为换到 access_token(长度 104,有效期 3600s) |
|
||||
| 服务端推送实现 | ✓ 就绪 | `push.json` provider `hms` enabled,app_id `6917616450599975320` |
|
||||
| 包内 client_id | ✓ 正确 | 打进 HAP 的 `module.metadata` = `2039846327155747840`,与 `agconnect-services.json` 一致 |
|
||||
| **平板取 token** | **✗ 失败** | 见下 |
|
||||
| 服务端 token 登记 | ✗ 空 | `push_tokens` 表 0 行 |
|
||||
|
||||
---
|
||||
|
||||
## 二 根因:华为侧拒绝这个「应用身份」
|
||||
|
||||
设备日志(`hilog`,`PushService` tag,抓取自一次 `force-stop` + 重启):
|
||||
|
||||
```
|
||||
I A00001/com.jianf.agentmail/PushService: push token 取不到(静默,属正常):
|
||||
Illegal application identity may be caused by incorrect clientid configuration.
|
||||
```
|
||||
|
||||
华为原话是 **`Illegal application identity may be caused by incorrect clientid configuration`**,
|
||||
即「应用身份非法,可能因 clientid 配置错误」。
|
||||
|
||||
### ★★ 2026-10-02 复测:根因比上面写的**更具体**,且已能定位到具体文件
|
||||
|
||||
重跑一次 `force-stop` + 启动,抓到一条上一轮**漏掉**的华为侧日志(`cloudinterfaceauth/AuthService`):
|
||||
|
||||
```
|
||||
E cloudinterfaceauth/AuthService: cert finger empty, clientId: 2039846327155747840,
|
||||
isTestEnv: 0, isSubApp: 0, Fingerprint: 153F****F919
|
||||
I PushService: push token 取不到:code=1000900010 Illegal application identity …
|
||||
```
|
||||
|
||||
**`cert finger empty`** —— 设备端报上来的是**空指纹**。这不是"指纹对不上 AGC",
|
||||
而是"**根本没有应用指纹可报**"。`bm dump` 与之吻合:
|
||||
|
||||
```
|
||||
"appSignType": "none" ← 签名类型:none
|
||||
"signatureKey": "" ← 签名身份:空
|
||||
```
|
||||
|
||||
### 真正的根因(三个指纹的实测对比)
|
||||
|
||||
| 证书 | SHA-256 | CN |
|
||||
|---|---|---|
|
||||
| `build-profile.json5` 里 `certpath` 指的 `.cer` | `DF:21:A3:C0:…:DF:3A:37` | **Huawei CBG Root CA G2** |
|
||||
| `.p7b` profile 内嵌 `development-certificate` | `FD:89:AC:53:…:FC:9D:09` | 靳睿(1681189977251159745)\,Development |
|
||||
|
||||
⇒ **工程签的是那张 CA 根证书,而 profile 绑定的应用证书是另一张**(CN 是开发者本人,
|
||||
不是 Huawei CA)。包里没有应用身份 ⇒ 设备算出空指纹 ⇒ HMS 判非法身份 ⇒ 拿不到 token。
|
||||
**这不是"debug 证书不被接受",是"签错了证书"。**
|
||||
|
||||
profile 侧其余要素都正常,已逐项排除:
|
||||
|
||||
- `"bundle-name": "com.jianf.agentmail"` ✓
|
||||
- `"type": "debug"`、`validity` 1789442580→1820978580 未过期 ✓
|
||||
- **平板 UDID 在 `device-ids` 里**:`678AFBFAD8DA9C110BBD8ABD83724BA951F9F9D6A881852BC51F0CA4BAC98EA7`
|
||||
(`bm get -u` 实测值,与 profile 逐字一致)✓ —— 所以装得上、跑得起来
|
||||
|
||||
### 试过的那条路(**没走通**,记下来免得重走)
|
||||
|
||||
把 `certpath` 改成 profile 内嵌的那张 dev cert(单张)→ hvigor 直接失败:
|
||||
|
||||
```
|
||||
ERROR: 11013004 Profile cert must a cert chain
|
||||
Error Message: cause in cert file: /root/.ohos/config/agentmail-dev.cer
|
||||
```
|
||||
|
||||
⇒ **`certpath` 要的是一条「应用证书 + 签发它的 CA」的链**,不是单张。
|
||||
而那张 dev cert 的签发者 `Huawei CBG Developer Relations CA G2` **本机没有**:
|
||||
`/root/.ohos/config/` 下 5 个 `.p7b` 里都只有
|
||||
`Root CA G2` / `HOS Profile Management Debug` / `Software Signing Service CA` 三张,
|
||||
`~/.ohos/config/material/` 里也没有任何证书(只有几个 16/48 字节的散列)。
|
||||
|
||||
⇒ 结论不变(要用户从 AGC/DevEco 导出完整那套),但**要的东西要说准**:
|
||||
不只是 `.cer`,而是**能构成链的整套**(应用证书 + 其签发 CA)。给一张单证书是装不上的。
|
||||
|
||||
---
|
||||
|
||||
### 需要纠正的一个先入判断
|
||||
|
||||
我一开始判断「HMS Push 只接受发布证书、debug 包必然拿不到 token」。**真机日志否证了它的表述**:
|
||||
报错指向的是 client_id / 应用身份,**没有**说 debug 证书不被接受。
|
||||
现在(2026-10-02)进一步定位到:问题**不在"debug 还是 release"这个轴上**,
|
||||
而在"**签的是哪张证书**"——签成了 CA 根,profile 却绑的是开发者应用证书。
|
||||
即使换成发布证书,如果仍然只拿到单张 `.cer` 而没有链,`certpath` 一样编不过。
|
||||
|
||||
---
|
||||
|
||||
## 三 要跑通完整闭环,需要你提供什么
|
||||
|
||||
本机只有**一套**签名,就是当前装在平板上的那套 debug 签名:
|
||||
|
||||
```
|
||||
/root/.ohos/config/default_harmony_k2yruKTLaTiZOjublhUDTfveVx5uFoHqm96pwkUw=.{cer,p12,p7b,csr}
|
||||
CN = Huawei CBG Root CA G2
|
||||
SHA256 = DF:21:A3:C0:9F:79:54:57:93:05:F8:5C:64:F8:0C:AD:86:F7:98:53:EE:3A:88:7C:1D:EC:95:D2:18:DF:3A:37
|
||||
→ 工程里 keyAlias 名为 debugKey,设备 appSignType=none
|
||||
```
|
||||
|
||||
`/root/.ohos/config/` 下另有 4 套(EcoArk / HelloWorld / HomeAgent / SlipOfNote),
|
||||
但它们是**别的应用**的证书——AGC 的包名与证书绑定,不能拿来签 `com.jianf.agentmail`。
|
||||
|
||||
**需要你从 AGC 后台 / DevEco Studio(应用 `com.jianf.agentmail`)导出:**
|
||||
|
||||
1. **应用证书 `.cer`** —— 注意要**能构成链**(见上:`11013004 Profile cert must a cert chain`)。
|
||||
最省事的是直接在 DevEco 里对这个工程 **Project Structure → Signing Configs → 同步签名**
|
||||
(它会自动取回正确的证书与链并改好 `build-profile.json5`)。
|
||||
2. 签名私钥 `.p12` + 其口令
|
||||
3. profile `.p7b`(当前这份已包含 `com.jianf.agentmail` 与这台平板的 UDID,
|
||||
实测可复用;若走发布通道则需重新导出含本机 UDID 的发布 profile)
|
||||
|
||||
拿到后我会做:
|
||||
|
||||
- 写入新的 `signingConfigs` 条目,**保留**现有 debug 配置(不破坏别的工程);
|
||||
- `devecocli build` 出签名正确的 HAP,`hdc install -r` 装到平板;
|
||||
- **先验签**:`bm dump` 里 `appSignType` 不再是 `none`、`signatureKey` 非空
|
||||
—— 这一步过了,才值得去重跑 token;
|
||||
- 真机重跑 token 获取 → 确认 `push_tokens` 出现 1 行;
|
||||
- 服务端发一封真实邮件 → 平板弹出通知 → **点通知**验证跳转到那封信(冷启 + 热启两条路径,
|
||||
后者是 2026-09-17 实测发现过的死路径)。
|
||||
|
||||
---
|
||||
|
||||
## 四 顺带发现、尚未处理的两点
|
||||
|
||||
1. **`click_action` 缺失**:服务端 `push/hms.go` 的 `notification` 只有 `title`/`body`,
|
||||
跳转信息全在 `data` 字符串里。华为的规范做法是 `click_action: {"type":1,"intentData":"..."}`。
|
||||
当前 `data` 解析路径可用,但点击行为的规范性未验证(待上面闭环跑通后在真机上看实际表现)。
|
||||
2. **`test_message: true`**:`push.json` 里开着。它让华为把消息记为「测试消息」(有独立配额,
|
||||
且不上架限制)。上架后需要关掉——这条在 `push_test.go` 里有判据守着,不会漏。
|
||||
|
||||
---
|
||||
|
||||
## 五 复现步骤(可重跑)
|
||||
|
||||
```bash
|
||||
export PATH=$PATH:/opt/huawei/command-line-tools/sdk/default/openharmony/toolchains
|
||||
D=192.168.2.87:43679
|
||||
hdc tconn $D # 连真机
|
||||
hdc -t $D shell "hilog -r" # 清缓冲
|
||||
hdc -t $D shell "aa force-stop com.jianf.agentmail"
|
||||
hdc -t $D shell "aa start -a EntryAbility -b com.jianf.agentmail"
|
||||
sleep 15
|
||||
hdc -t $D shell "hilog -x | grep PushService" # ← 报错在这里
|
||||
|
||||
# 服务端侧
|
||||
sqlite3 /opt/agentmail/data/agentmail.db "SELECT * FROM push_tokens;" # 空
|
||||
journalctl -u agentmail-gateway --since '1 hour ago' | grep -i push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六 自证边界
|
||||
|
||||
- 「服务端凭证有效」是**实测**:真的换到了 access_token。
|
||||
- 「根因是证书不匹配」是**推断**:三项绑定要素里包名与 client_id 已证实正确,
|
||||
证书指纹与 AGC 侧登记值的比对**没法在本机完成**(AGC 后台值需登录网页查看)。
|
||||
⇒ 该结论要等换上发布证书后**复测**才算定案;若换签名后仍报同一错,
|
||||
则应转查 AGC 后台该 client_id 绑定的包名/证书。
|
||||
- 「HMS Push 不接受 debug 包」这句**已撤回**,理由见 §二。
|
||||
Reference in New Issue
Block a user