无尘阁日记

无尘阁日记

App 签名证书到底是怎么生成出来的?
silcano

开发者可以随便填安卓证书的主体名称,却填不了 iOS 和鸿蒙的,因为后面这两张证书都得苹果和华为签字。同样叫做签名证书,三张纸的生成机制完全不一样。下面把它拆到根子上讲清楚。

证书的根子是一对密钥,加一张证明公钥归属的纸。私钥留在自己手里负责签名,公钥写进证书交给别人验证。这张纸由谁签字,就决定了主体名称由谁定。

这张纸的学名叫做 X.509 数字证书,里面有一段字段叫做 DN,中文叫做可分辨名称。DN 装着通用名、组织单位、组织名称、城市、省份、国家这六样东西。安卓的 DN 由生成的人直接填写,iOS 和鸿蒙的 DN 由签发方填写。

· · ·

先说安卓,一条 keytool 命令能一口气生成密钥对、自签证书和 JKS 仓库文件。命令里的 -dname 参数就是填写 DN 的位置,公司全称写进 CN 字段或者 O 字段都可以。生成出来的 .keystore 文件同时装着私钥和证书,设置密码就算完工。

所以工具表单只要五样材料:主体名称、密钥别名、密码、有效年数、密钥算法。主体名称建议照抄营业执照上的公司全称,别名固定用 release,有效年数设成三十年,算法认准 RSA 2048。密码一定要保管好,私钥丢失就永远更新不了这个应用。

HBuilderX 云打包的云证书就卡住在这一步。DCloud 服务器生成证书时自动填写证书信息,不支持自定义证书信息,有效期固定一百年。想让证书里写着甲方公司名称,云证书这条路走不通,只能自己生成再传上去。

生成的时候还有格式岔路。JKS 是 Java 老格式,仓库密码和密钥密码可以分开设置;PKCS12 是新标准,两个密码必须相同。工具输出标准 JKS 并把两个密码设成一样,是为了兼容 Android 全家桶。

· · ·

再说 iOS,玩法完全变了,本地只能生成密钥对和 CSR 请求文件。真正的证书必须提交给苹果签发,主体写的是 Apple Distribution 加上团队名称和 Team ID。团队名称就是开发者账号注册时的公司名称,想换主体名称只能换账号,没有第二条路。

因此 iOS 要准备的是苹果开发者账号、公司资质、D-U-N-S 编号、App ID 和描述文件。公司账号年费九十九美元,还得通过苹果的资质审核。CSR 里随便填名字没有意义,苹果会按团队信息重写证书主体。

纯血鸿蒙跟 iOS 是一个模子刻出来的。本地生成 p12 密钥库和 csr 请求文件,上传到 AppGallery Connect 申请 cer 证书。要准备华为开发者账号、企业实名认证、包名和签名证书指纹。

华为签出来的证书还配一张 p7b 描述文件,文件里绑死包名、权限列表和设备列表。鸿蒙的 DN 字段有一道硬限制。姓名、组织、组织单位这些字段只接受字母和空格,长度不超过六十四个字符,中文公司名填不进去。

· · ·

证书生成完还有备案这一步。备案要的不是证书文件,而是证书里的公钥模数和指纹。安卓填 MD5,iOS 填 SHA1,公钥填 RSA 模数 n 的十六进制,注意不带 ASN.1 外层包装。

解析工具的做法是把 APK 或者证书文件解开,从签名块里取出 X.509 证书,再拆开证书提取公钥。RSA 公钥是 ASN.1 结构,去掉包装就拿到 n 和 e 两个参数。指纹对证书的 DER 字节流计算 MD5 或者 SHA1 就出来。

卡点集中在四个地方。第一,主体名称的自由度:安卓完全自由,鸿蒙只能填字母,iOS 零自由。第二,私钥保管:私钥丢失就永远更新不了应用,密码忘记等于丢失私钥。

第三,更换签名等于更换应用。已经上架的应用更换证书,用户端会安装冲突,必须卸载重装。第四,有效期有硬杠杠,Google Play 要求发布证书有效到二零三三年十月之后,所以有效年数不要设太短。

自己的工具省掉的是两件麻烦事情。一是记住一堆 keytool 参数,二是跟大模型来回确认命令格式。表单填完点击生成,证书和解析结果一次到位。