# 华为正式发布证书申请 + 家书切 release 签名 > **一句话结论**:现在用的是**调试证书**,它能装到自己手机,但**不能上架、不能用于 APP 备案**。 > 必须先生成**正式发布证书(.cer)+ 发布 Profile(.p7b)**,再改 `build-profile.json5` 切到 release。 --- ## 一、先确认现状(已核实) `build-profile.json5` 当前签名配置: ```json5 { "name": "default", "type": "HarmonyOS", "material": { "certpath": "/home/yongquan/code/cert/familybook/familybook.yangyq.net.debug.cer", "keyAlias": "debugKey", "profile": ".../familybook.yangyq.net.debug.p7b", "signAlg": "SHA256withECDSA", "storeFile": ".../familybook.yangyq.net.debug.p12" } } ``` 文件名里带 `.debug.` —— **这是调试证书**。它的特征: | 项目 | 调试证书 | 发布证书 | |---|---|---| | 有效期 | 约 90 天(会过期) | **1 年**(可续) | | 可装机范围 | 仅登记过的调试设备(UDID 白名单) | **任意设备** | | 能否上架 AppGallery | ❌ **不能**(审核报 991 / 1014) | ✅ 必须 | | 能否用于 APP 备案 | ❌ **不能**(备案要正式证书的公钥/MD5) | ✅ 必须 | | 能否用于 Map Kit | ✅ 可以(这也是之前 #33 的前提之一) | ✅ 可以 | ### 实测当前调试证书的指纹 ``` MD5 : 7D:0C:4B:46:B7:C1:C0:D2:3C:6E:43:16:E5:C9:96:A3 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 公钥 : MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrsGUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpLMBwcz4DA0kgHCMm/wDec6kOHx1xvCR ``` > ⚠️ **这三项是调试证书的,不能拿去备案**。备案必须是正式证书的。 --- ## 二、申请正式发布证书(AGC 网页操作,约 10 分钟) ### 前置:确认开发者账号已实名 AGC → 右上角头像 → 「实名认证」。个人开发者需身份证 + 人脸/银行卡验证,通常 1–3 个工作日。 **你之前上架过 SyncCalendar,说明已实名,可跳过。** ### 步骤 1:生成 CSR + 密钥库(在 WSL 里做) 华为的 `.cer` 是**用你本地生成的 CSR 去换**的,私钥始终在你手里,不上传。 ```bash cd ~/code/cert/familybook # 生成密钥库(PKCS#12)与 CSR # ⚠️ 口令自己定,记牢 —— 每次打包都要输,丢了只能重新申请证书 keytool -genkeypair \ -alias familybook_release \ -keyalg EC -groupname secp384r1 -sigalg SHA384withECDSA \ -validity 3650 \ -keystore familybook.yangyq.net.release.p12 \ -storetype PKCS12 \ -dname "C=CN, O=yangyq, OU=personal, CN=familybook.yangyq.net" \ -storepass '<你的口令>' -keypass '<同一个口令>' # 导出 CSR keytool -certreq \ -alias familybook_release \ -keystore familybook.yangyq.net.release.p12 \ -storepass '<你的口令>' \ -file familybook.yangyq.net.release.csr ``` 产出: - `familybook.yangyq.net.release.p12`(**私钥,绝不上传、务必备份**) - `familybook.yangyq.net.release.csr`(这个拿去换证书) > 💡 也可以直接在 DevEco Studio 里做:`Build → Generate Key and CSR`,效果一样。 > 但你在 WSL 命令行做更可控,且方便脚本化。 ### 步骤 2:在 AGC 上传 CSR,换回 .cer 1. 登录 https://developer.huawei.com/consumer/cn/service/josp/agc/index.html 2. 右上角「我的」→ **「用户与访问」** → 左侧 **「证书管理」** 3. 点 **「新增证书」** 4. 证书类型选 **「发布证书」**(Release,不是 Debug) 5. 上传刚生成的 `familybook.yangyq.net.release.csr` 6. 提交 → 下载得到 **`familybook.yangyq.net.release.cer`** 7. 把这个 `.cer` 放到 `~/code/cert/familybook/` > ⚠️ 一个账号最多 1 个**发布证书**(调试证书可多个)。若已有(SyncCalendar 用的那个), > 需要先**吊销**旧的才能新建 —— 但吊销会让 SyncCalendar 的更新包签不了名, > **所以建议:给家书单独申请前,先确认是不是共用同一个。** > > 更稳妥的做法:**同一个发布证书可以签多个应用**(Profile 才是按应用绑定的), > 所以直接用 SyncCalendar 那个发布证书也行,只需为家书新建一个 **Profile**。 ### 步骤 3:创建发布 Profile(按应用绑定) 1. 还在「用户与访问」→ 左侧 **「Profile」** 2. 点 **「新增 Profile」** 3. Profile 类型选 **「发布」** 4. 绑定: - **应用**:选「家书」(若 AGC 里还没建这个应用,先去「我的应用 → 新建」建一个) - **证书**:选上一步那个发布证书 5. 提交 → 下载得到 **`familybook.yangyq.net.release.p7b`** > ⚠️ Profile 与**包名**绑定。家书包名 `familybook.yangyq.net`, > 必须与 AGC 里创建应用时填的包名**完全一致**。 ### 步骤 4:配置应用包名与指纹(备案也要用) 1. AGC →「我的应用」→ 新建(如果还没建) - 平台:**HarmonyOS** - 应用名称:**家书** - 包名:**familybook.yangyq.net**(一字不差,**创建后不可改**) - 分类:实用工具 - 默认语言:简体中文 2. 「项目设置 → 常规 → 应用」→ **添加公钥指纹** - 上传步骤 2 下载的 `.cer`,或直接填 SHA256 指纹 3. 顺手把 **「应用」的 Client ID** 记下来(工单 #33 的 Map Kit 要用它) --- ## 三、切换到 release 签名(改代码) `build-profile.json5` 目前只有 `default` 一个 signingConfig。**不要直接改掉它** (否则日常调试也得用发布证书,很麻烦),而是**新增一个 release 配置**: ```json5 { "app": { "signingConfigs": [ { // 保留原调试配置,日常装机继续用它 "name": "default", "type": "HarmonyOS", "material": { "certpath": ".../familybook.yangyq.net.debug.cer", "keyAlias": "debugKey", "profile": ".../familybook.yangyq.net.debug.p7b", "signAlg": "SHA256withECDSA", "storeFile": ".../familybook.yangyq.net.debug.p12", "storePassword": "...", "keyPassword": "..." } }, { // 🆕 发布用(上架 / 对外分发) "name": "release", "type": "HarmonyOS", "material": { "certpath": "/home/yongquan/code/cert/familybook/familybook.yangyq.net.release.cer", "keyAlias": "familybook_release", "profile": "/home/yongquan/code/cert/familybook/familybook.yangyq.net.release.p7b", "signAlg": "SHA256withECDSA", "storeFile": "/home/yongquan/code/cert/familybook/familybook.yangyq.net.release.p12", "storePassword": "<你的口令>", "keyPassword": "<同一个口令>" } } ], "products": [ { "name": "default", "signingConfig": "release", // ← 只改这一处 "targetSdkVersion": "26.0.0", "compatibleSdkVersion": "6.1.1(24)", "runtimeOS": "HarmonyOS" } ] } } ``` 打包: ```bash source ~/.workbuddy/env/harmonyos.sh cd ~/code/FamilyBook_harmonyos # AppGallery 只收 .app(App Pack),不是 .hap hvigorw --mode module -p product=default -p buildMode=release assembleApp --no-daemon ``` 产出在 `build/default/outputs/default/` 下的 **`.app`** 文件。 ### 打完后务必自检这三条 ```bash # ① 确认是 .app 不是 .hap ls -la build/default/outputs/default/*.app # ② 确认签名用的是发布证书(不是 debug) # 解包看签名信息,证书 CN 里不应出现 "debug" unzip -l xxx.app | head # ③ 确认版本号 unzip -p xxx.app/entry/... module.json | grep -E 'versionName|versionCode' ``` --- ## 四、拿到正式证书后,顺手做 APP 备案 **备案需要的三项,只有正式证书才能提供:** ```bash cd ~/code/cert/familybook # ① 公钥 openssl x509 -in familybook.yangyq.net.release.cer -pubkey -noout # ② 签名 MD5(备案用,**去掉冒号**!) openssl x509 -in familybook.yangyq.net.release.cer -fingerprint -MD5 -noout # ③ 包名(在 app.json5 里,已知) grep bundleName ~/code/FamilyBook_harmonyos/AppScope/app.json5 ``` > ⚠️ 备案系统的 MD5 字段要求**去掉冒号**,小写或大写都行但要去掉分隔符。 > 例如 `7D:0C:4B:...` → `7d0c4b46b7c1c0d2...` --- ## 五、证书有效期与续期 | 项 | 有效期 | 到期后果 | |---|---|---| | 发布证书 `.cer` | **1 年**(自签发日) | 到期后无法用该证书签新包;已上架的应用仍可运行,但**无法发布更新** | | 发布 Profile `.p7b` | 跟随证书 | 同上 | | 密钥库 `.p12` | 你设的 validity(建议 10 年以上) | 丢了就永远无法再签同名应用 | ### 🔴 必须做的事 1. **`.p12` 私钥文件务必备份**(至少两地)。**它丢了 = 这个包名以后再也发不了更新**, 只能换包名重新上架,等于从零开始积累下载量。 2. 在日历里设一个**证书到期前 60 天**的提醒。 3. 续期方式:AGC 重新走一遍「新增证书 → 上传 CSR → 下载 .cer」,并**重建 Profile**。 > 用**同一个密钥库**重新生成 CSR 时,公钥不变,指纹也不变 —— 这样对已上架应用最省事。 --- ## 六、常见坑(提前避开) | 坑 | 现象 | 原因与解法 | |---|---|---| | 拿调试证书打包上架 | 上传成功,进审核后报 **991 / 1014** 包无效 | 必须用发布证书 + 发布 Profile | | Profile 包名对不上 | 上传时报"包名与 Profile 不匹配" | Profile 绑包名,AGC 建应用时包名必须一字不差 | | 忘了加公钥指纹 | Map Kit 报 `1002600004` / 地图不显示 | AGC「项目设置 → 常规 → 应用」添加 SHA256 指纹 | | 私钥口令忘记 | 无法打包 | 只能重新申请证书(可用同一 CSR 会得到同公钥) | | 传了 `.hap` | AGC 不认 | 必须是 `.app`(`assembleApp`,不是 `assembleHap`) | | versionCode 没递增 | 上传被拒 | 每次上传都要比上次大 | --- ## 七、时间预期 | 环节 | 耗时 | |---|---| | 本地生成 CSR | 2 分钟 | | AGC 签发证书 | **即时**(网页直接下载) | | AGC 创建 Profile | **即时** | | 本地切签名 + 打 release 包 | 5 分钟 | | **AppGallery 审核** | **1–7 个工作日**(首次通常更久) | | **APP 备案(阿里云初审)** | 1–2 个工作日 | | **APP 备案(管局审核)** | **1–20 个工作日**(多数省份约 7 天) | > 备案是最慢的一环。**建议顺序:先申请正式证书 → 同时提交 APP 备案 → 备案通过后再提审应用。** > 因为华为要求上架时填写 APP 备案号,没有备案号会被拒。