Https 证书
现在网络安全越来越受重视,通用做法是采用 https 加密通信,使用 https 需要数字证书,只有合法的证书才能被浏览器、操作系统默认支持。
所谓的合法证书其实是在 CA 公司那购买的(原来我们的合法性是花钱从别人那买来的,不得不吐槽这种互联网安全设计真是坑爹),虽然现在也有一些免费 CA 证书,但申请还是挺麻烦,这里我们使用自签名的 https 证书,基于这种没有经过 CA 机构签名的证书,也可以实现 Android 与服务端之间的加密通信。
服务端使用 https
生成 https 证书
JDK 自带的 keytool 工具可以很方便生成 https 证书,可以查看它的使用方法:

比如这条命令就可以生成一个有效期 10 年的证书:
1 | keytool -genkey -alias spring -validity 3560 -keystore spring.keystore |
服务端配置 https 证书
服务端一般使用 Tomcat、Jetty、Undertow 等作为 Servlet 容器,我们将上面生成的 keystore 证书放在项目中,然后在配置文件中引入证书即可:
1 | server.ssl.key-store=spring.keystore |
这样服务端就支持 https 了,启动项目访问服务就要加 https 前缀,如 https://localhost:8080/user
Android 自定义 https 校验
如果是花钱买的 CA 证书是不需要额外配置的,Android 系统内部有信任列表,会自行校验通过,这里讲配置自定义 https 校验。
Android 端通常使用 Retrofit 做网络请求,Retrofit 底层就是 OKhttp,OKhttp 实现自定义 https 校验并不难,主要分三步。
把证书公钥预埋在 APP 中
这条命令可以导出证书公钥字符串:
1 | keytool -list -rfc -keystore spring.keystore |

把这个公钥作为一个字符串常量放在项目中供后面校验使用。
自定义证书校验逻辑
使用上面的公钥字符串构建 X509TrustManager 对象,在 checkServerTrusted 方法中校验服务端证书:
1 | X509TrustManager trustManager = new X509TrustManager() { |
设置 OkHttpClient 校验证书
然后使用上面的 trustManager 构建 OkHttpClient
1 | SSLSocketFactory sslSocketFactory = null; |
使用这个配置好的 OkHttpClient 与服务端交互,就可以支持自定义 https 证书加密通信了,如果服务端证书不符,请求会自动断开。

