Android与服务端使用Https加密通信

Android与服务端使用Https加密通信

大家好,又见面了,我是全栈君。

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.keystore
server.ssl.key-alias=spring
server.ssl.key-password=password
server.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证书加密通信了,如果服务端证书不符,请求会自动断开。

扫一扫关注我的微信公众号
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108148.html原文链接:https://javaforall.net

(0)
上一篇 2022年3月7日 上午9:00
下一篇 2022年3月7日 上午9:00


相关推荐

  • LTE学习之路(15)——QCI

    LTE学习之路(15)——QCIQCI表示QoS类别指示。这是一种特定标识,其定义了LTE数据包通信的质量QCI类别范围:1~9(每个类别的定义如下表所示)注意:通过‘ActivatedefaultEPSbearercon

    2022年8月4日
    5
  • 单目摄像机标定程序「建议收藏」

    单目摄像机标定程序「建议收藏」我自己写了一个摄像机标定程序,核心算法参照learningopencv,但是那个程序要从命令行预先输入参数,且标定图片要预先准备好,我觉得不太好,我就自己写了一个,跟大家分享下。若有纰漏,希望大家指正!#include”stdafx.h”#include”cv.h”#include”highgui.h”#include#includeusingname

    2025年6月13日
    6
  • 经常使用的DB2命令(2)

    经常使用的DB2命令(2)

    2022年1月28日
    46
  • 视频直播技术详解之一:开篇

    视频直播技术详解之一:开篇随着互联网用户消费内容和交互方式的升级,支撑这些内容和交互方式的基础设施也正在悄悄发生变革。手机设备拍摄视频能力和网络的升级催生了大家对视频直播领域的关注,吸引了很多互联网创业者或者成熟企业进入该领域。七牛云作为一家以基础服务能力见长的云计算公司,于6月底发布了一个针对视频直播的实时流网络LiveNet和完整的直播云解决方案,很多开发者对这个网络和解决方案的细节和使用场景非常感兴趣

    2022年7月21日
    19
  • Linux 抓包工具 tcpdump 用法

    Linux 抓包工具 tcpdump 用法Linux抓包工具tcpdump用法tcpdump采用命令行方式对接口的数据包进行筛选抓取,其丰富特性表现在灵活的表达式上。不带任何选项的tcpdump,默认会抓取第一个网络接口,且只有将tcpdump进程终止才会停止抓包。例如:tcpdump-nn-ieth0icmp下面是详细的tcpdump用法tcpdump选项它的命令格式为:tcpdump[-DenNqvX][-ccount][-Ffile][-iinterface][-rfile]

    2022年8月20日
    8
  • QuoteName\生成Sql语句

    QuoteName\生成Sql语句ifexists(selectnamefromtempdb.dbo.sysobjectswhereid=object_id(N’tempdb.dbo.#tempWorkDate’)andtype=’u’)droptable#tempWorkDateCREATETABLE[#tempWorkDate]([WorkDate][varc…

    2026年4月13日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号