Android与服务端使用Https加密通信
来源:互联网 发布:青年网络公开课 2017 编辑:程序博客网 时间:2024/06/06 01:05
Https证书
现在网络安全越来越受重视,通用做法是采用https加密通信,使用https需要数字证书,只有合法的证书才能被浏览器、操作系统默认支持,而所谓的合法证书是在CA公司那购买的(原来我们的合法性是花钱从别人那买来的,不得不吐槽这种互联网安全设计真是坑爹),虽然现在也有一些免费CA证书,但申请还是挺麻烦,这里我们使用自己生成的https证书。
服务端使用https
生成https证书
JDK自带的keytool工具可以很方便生成https证书,可以查看它的使用方法:
比如这条命令就可以生成一个有效期10年的证书:
keytool -genkey -alias spring -validity 3560 -keystore spring.keystore
服务端配置https证书
服务端一般使用Tomcat、Jetty、Undertow等作为Servlet容器,我们将上面生成的keystore证书放在项目中,然后在配置文件中引入证书即可:
server.ssl.key-store=spring.keystoreserver.ssl.key-alias=springserver.ssl.key-password=passwordserver.ssl.key-store-type=JKS
这样服务端就支持https了,启动项目访问服务就要加https前缀,如 https://localhost:8080/user
Android自定义https校验
如果是花钱买的CA证书是不需要额外配置的,Android系统内部有信任列表,会自行校验通过,这里讲配置自定义https校验。
Android端通常使用 Retrofit 做网络请求,Retrofit底层就是OKhttp,OKhttp实现自定义https校验并不难,主要分三步。
把证书公钥预埋在APP中
这条命令可以导出证书公钥字符串:
keytool -list -rfc -keystore tomcat.keystore
把这个公钥作为一个字符串常量放在项目中供后面校验使用。
自定义证书校验逻辑
使用上面的公钥字符串构建X509TrustManager对象,在checkServerTrusted方法中校验服务端证书:
X509TrustManager trustManager = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { //校验客户端证书 } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { //校验服务端证书 X509Certificate ca = (X509Certificate) CertificateFactory.getInstance("X.509") .generateCertificate(new ByteArrayInputStream(PUB_KEY.getBytes())); for (X509Certificate cert : chain) { // 检查服务端证书是否过期 cert.checkValidity(); try { //和APP预埋证书对比 cert.verify(ca.getPublicKey()); } catch (Exception e) { //证书校验异常 throw new SecurityException("证书错误!"); } } } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }};
注意证书校验异常时抛出一个SecurityException,如果不抛出这个RuntimeException,程序会继续执行,请求依然正常,证书校验就没有意义。
设置OkHttpClient校验证书
然后使用上面的trustManager构建OkHttpClient
SSLSocketFactory sslSocketFactory = null;try { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{trustManager}, new SecureRandom()); sslSocketFactory = sslContext.getSocketFactory();} catch (NoSuchAlgorithmException | KeyManagementException e) { e.printStackTrace();}final HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(final String hostname, final SSLSession session) { //服务端主机域名地址校验 return true; }};OkHttpClient client = new OkHttpClient.Builder() .hostnameVerifier(hostnameVerifier) .sslSocketFactory(sslSocketFactory, trustManager) .build();
使用这个配置好的OkHttpClient与服务端交互,就可以支持自定义https证书加密通信了,如果服务端证书不符,请求会自动断开。
扫一扫关注我的微信公众号
- Android与服务端使用Https加密通信
- android如何与服务端通信
- android 使用https与服务器进行通信交互
- android使用https通信总结
- https通信加密过程
- Android与Java服务端加密解密
- php服务端与android客户端socket通信
- php服务端与android客户端socket通信
- php服务端与android客户端socket通信
- Android之与服务端通信一
- Android与服务端通信之JSON格式
- android 蓝牙客户端与服务端通信
- php服务端与android客户端socket通信
- 基于WebSocket的Android与服务端通信
- Android 用Https协议与服务器通信
- https加密通信过程图解
- https 加密通信实现示例
- 使用Mina框架开发 QQ Android 客户端(2) 客户端与服务端的通信
- java多态的一些问题
- 如何学习嵌入式? 嵌入式之路从入门到放弃....
- java根据输入提取所需
- HDU 2833 WuKong 求两条最短路间最多公共点数
- 设计模式(三)——工厂方法模式
- Android与服务端使用Https加密通信
- centos7安装ycm无代码补全
- 大话设计模式之装饰模式
- 划分子网和构造超网
- HDU 6195 推公式
- LeetCode-Add Two Numbers
- shell通过端口号获取PID(进程号)
- 不要使用sun.misc.BASE64Encoder
- 最全Pycharm教程(30)——Pycharm中的File Watchers