HarmonyOS 鸿蒙Next中在http网络框架中启用 Certificate Pinning 报错 pin not match
HarmonyOS 鸿蒙Next中在http网络框架中启用 Certificate Pinning 报错 pin not match 用原生的 http 发送一个get 请求,在 certificatePinning 传入两个中间证书的 hash 值,一直报错 not match, 而这两个 hash 在 Android 或 iOS 中是 macth 的,debug 发现好像只能匹配 leaf certificate 的 hash,请问 http 支持证书链的校验吗?如果有,应该怎么配置?
若用的Network kit的HTTP网络请求能力,支持证书锁定(Certificate Pinning)。
-
先获取证书公钥哈希值。参看《证书锁定》或者直接运行下面命令,替换baidu.com为你自己的域名。
openssl s_client -servername baidu.com -connect baidu.com:443 | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64 -
配置方式有两种:
· network_config.json配置文件里配置。参看《证书锁定》。
· 代码里配置。参看《API完整示例》。
更多关于HarmonyOS 鸿蒙Next中在http网络框架中启用 Certificate Pinning 报错 pin not match的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
HarmonyOS的CA我还没对接过,不过参考Andorid和iOS的实现从现象来看,像是 HarmonyOS 当前 http 框架的 Certificate Pinning 实现只校验了服务端最终返回的 Leaf Certificate,并没有对整个证书链中的 Intermediate Certificate 做 Pin 匹配。
你的验证结果也印证了这一点:
- Android / iOS 使用中间证书 Hash 可以匹配成功;
- HarmonyOS 传入中间证书 Hash 一直报
pin not match; - 换成 Leaf Certificate 的 Hash 后可以匹配。
如果确实是这样,那么当前框架可能并不支持类似 OkHttp 那种“证书链任意节点匹配即通过”的 Pinning 机制,而是仅针对 Leaf Certificate 做校验。
建议再确认两点:
- 传入的 Hash 是否为 Leaf Certificate 公钥的 SHA-256 值;
- 服务端实际下发的证书链是否完整(抓包或 openssl 查看)。
如果确认中间证书 Hash 在 Android、iOS 均能通过,而 HarmonyOS 始终只能匹配 Leaf Certificate,那么大概率属于当前 http Certificate Pinning 能力的实现限制,而不是配置问题。
目前我也没有看到官方文档明确说明支持 Intermediate CA 或整条证书链的 Pin 校验。如果业务必须依赖中间证书 Pinning,可能需要进一步向华为确认当前版本是否支持该能力,提交个工单试试。
补充一个可验证的排查方向:这里要把“证书链是否可信”和“证书锁定 pinning”分开。证书链校验走 caPath/caData 或 network_config.json 的 trust-anchors;certificatePinning 锁的是 server certificate public key 的 SHA-256/Base64,不是把中间 CA 证书文件整体 hash 后填进去。你看到只能匹配 leaf,和官方示例里的语义基本一致。
publicKeyHash 建议按服务端实际返回的 leaf 证书来算,注意要算 SPKI/public key,而不是证书 DER/PEM 全量 hash:
openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null | awk '/BEGIN CERTIFICATE/{i++} i==1{print} /END CERTIFICATE/{if(i==1) exit}' > leaf.pem
openssl x509 -in leaf.pem -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | openssl base64
Network Kit 动态配置可类似这样:
httpRequest.request('https://api.example.com', {
method: http.RequestMethod.GET,
certificatePinning: [
{ publicKeyHash: 'leaf公钥hash的Base64', hashAlgorithm: 'SHA-256' },
{ publicKeyHash: '备用leaf公钥hash的Base64', hashAlgorithm: 'SHA-256' }
]
}, callback);
另外要确认请求域名、SNI、CDN 节点一致;如果服务端会返回多套 leaf 证书,就把实际可能命中的公钥 hash 都作为 pin 配进去。参考:网络连接安全配置 SSL Pinning、http 的 certificatePinning 参数、http-request 的证书锁定章节。
这个现象大概率不是证书链校验没生效,而是 pin 的对象理解有偏差。HarmonyOS 的 http.certificatePinning 字段名叫 publicKeyHash,官方网络安全配置里也写的是“服务器证书公钥”的 Hash;也就是说它做的是 SSL Pinning / public key pinning,用来锁定服务端实际证书公钥,而不是把中间 CA 证书链里的任意 hash 都当作可匹配对象。
所以你传两个中间证书的 hash,Android/iOS 能 match,不代表 HarmonyOS http 也会按同样策略匹配。你 debug 看到只匹配 leaf certificate,和文档描述是一致的。建议用服务端当前叶子证书的 SPKI SHA-256 作为主 pin,再准备一个备用公钥,避免证书轮换时线上全量失败。
ArkTS 动态配置示例:
import { http } from '@kit.NetworkKit';
const req = http.createHttp();
req.request('https://example.com/api', {
method: http.RequestMethod.GET,
certificatePinning: [
{
publicKeyHash: '叶子证书SPKI的base64-sha256',
hashAlgorithm: 'SHA-256'
},
{
publicKeyHash: '备用服务器公钥hash',
hashAlgorithm: 'SHA-256'
}
]
}, (err, data) => {
req.destroy();
});
排查时可先用 openssl 导出目标域名握手返回的 leaf 证书,计算 Subject Public Key Info 的 SHA-256,而不是直接算整张证书文件或中间证书的 hash。若业务目标是限定可信 CA 链,应走 caPath / network_config.json 的 trust-anchors;若目标是锁定服务器身份,再用 certificatePinning。
参考资料:
https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-http#httprequestoptions
你这里问的应该是 HTTPS 场景。certificatePinning 通常锁定的是服务器证书公钥的 SHA-256 hash,而不是把中间 CA 证书的整张证书 hash 填进去就能匹配。
建议先确认三件事:1. 计算的是 SPKI/public key hash,并按文档要求做 Base64,而不是证书文件 DER/PEM 的整体 hash;2. 当前服务端实际返回的 leaf certificate 公钥是否和你填入的一致,可以用抓包或 openssl 查看证书链后逐个算;3. 至少配置当前 leaf 公钥和备用公钥,避免服务端换证后全部请求失败。
CA 链校验和 pinning 是两层能力:CA 信任用于验证证书链是否合法,pinning 用于进一步锁定指定公钥。如果你想信任某个中间 CA,更像是 caPath/network_config 的信任锚配置,不是 certificatePinning 的主要用法。
-
通过API校验指定证书是否可信:可参考networkSecurity.certVerification。
-
通过openssl命令校验域名服务器证书链是否被系统信任:hdc shell openssl s_client -connect 主机名:端口 -CApath /etc/security/certificates -brief。若出现Verification: OK说明证书链可信。将-trace -showcerts替换为-brief可以打印详细的TLS握手信息。
证书模块 validate(param: CertChainValidationParameters): 校验证书链
期待HarmonyOS能继续优化多屏协同功能,让跨设备体验更加完美。
在HarmonyOS鸿蒙Next的网络框架中启用Certificate Pinning时,“pin not match”表示客户端配置的证书公钥哈希值与服务器实际提供证书的公钥哈希值不一致。常见原因:配置的pin使用了错误的公钥(如Intermediate CA而非Leaf)、哈希算法不匹配(如SHA-256需编码为base64)、或服务器证书已更新。请重新提取并核对服务器证书的正确公钥及对应哈希值。
HarmonyOS Next的http模块CertificatePinning仅校验服务器终端实体证书(leaf certificate),不会遍历证书链中的中间证书进行匹配,这是与Android/iOS证书锁定行为的关键差异。因此直接传入中间证书hash会触发“pin not match”。若需固定证书链中的某个证书,目前只能使用服务器实际返回的叶子证书的SHA256哈希值进行配置。配置示例:
http.createHttp().request('https://example.com', {
certificatePinning: {
hash: 'leaf-certificate-sha256-base64', // 必须是叶子证书的SHA256 Base64编码
type: http.HttpCertificatePinningType.SHA256, // 默认SHA256
}
})
若业务必须锁定中间证书或根证书,需自行借助三方库实现自定义ssl证书校验。


