iOS 访问使用自签名证书服务
18 May 2018起因
最近被一位前端同事咨询怎么通过 iOS
微信浏览器访问本地使用自签名证书服务,略微折腾了下,有不少小坑,感觉还是值得记录一下。需要注意的是,我们是在类似微信浏览器这种非我们可控的浏览器环境下,而不是原生应用下访问 https
服务 —— 原生应用可以通过重写证书链信任流程来实现,详见Customising HTTPS Server Trust Evaluation
。
服务架设
本地服务使用 node
搭建,具体流程可以参考 《Painless Self Signed Certificates in node.js
》,其他语言/环境大体配置相差不大。
步骤如下
- 签发
CA
证书和私钥 - 通过
CA
证书签发下一级的证书,即后续需要用到的服务端证书和私钥 - 在
node
配置使用对应的证书和私钥
iOS 设置
由于证书一般是签发给域名,所以后续只能通过域名进行访问:理论上证书也是可以签发给 IP
,但我并没有做相应尝试,主要考虑到本地 IP
有可能经常变动,反倒是域名更加方便。
但由于 iOS
设备无法直接设置 Host
,所以这个流程相对会比较曲折。
- 在
mac
中修改Host
,将127.0.0.1
指向上一步中签发证书对应的域名 - 通过
Charles
之类的工具开启本地代理 - 在
iOS
端设置代理为mac
的IP
地址 - 将
CA
证书导入至iOS
设备 - 通过
设置
-通用
-关于本机
-证书信任设置
设置信任当前导入CA
证书 - 通过
iOS
中的微信浏览器直接访问https
地址
备注
-
必须通过
CA
证书签发下一级证书,而 不能直接使用自签名证书,否则后续证书链校验将失败。一般会出现类似DEPTH_ZERO_SELF_SIGNED_CERT
错误 -
原
wiki
代码中会有注入证书私钥的过程,在实际操作中并不需要 -
在
mac
中使用Chrome
访问时,即使系统选择信任当前CA
证书也是无用,建议在配置时使用Safari
做测试 (神坑) -
现在
Let's Encrypt
已然非常成熟,且由他们签发的证书已经被绝大部分系统和浏览器所信任,所以最方便的路径是通过他们进行证书签发,而不再需要往iOS
设备导入CA
证书 -
iOS
方面关于HTTPS
认证的技术细节,推荐阅读 Technical Q&A QA1948 和 Technical Note TN2232