启用服务器与客户端之间的HTTPS通信

时间:2020-04-19 09:18:12

标签: android ssl https certificate okhttp

我已经构建了一个服务器应用程序和一个Android应用程序。到目前为止,他们正在通过http进行通信,但是我正在每个请求中发送敏感信息(例如JWT)。因此,我没有使用Https。

我已经生成了p12证书。

在服务器端:

  1. 我已将证书复制到resources/keystore/sampleName.p12
  2. 我已将这些行添加到我的application.properties

    server.ssl.key-store-type=PKCS12
    server.ssl.key-store-password=samplePassword
    server.ssl.key-store=classpath:keystore/sampleName.p12
    server.ssl.key-alias=sampleName
    

在android端,我使用okHttp并像这样创建客户端

val httpClient = OkHttpClient.Builder()
    .certificatePinner(
        CertificatePinner.Builder()
            .add(
                https://10.0.2.2:8080,
                "sha256/lVIcG+gpmlabsq1bW5RbvB+kqVSHKdOFyoxjo9+SLEs="
            ).build()
    )
    .build()

我使用https://10.0.2.2:8080是因为我只在本地运行服务器应用程序,而且我还在同一台笔记本电脑上的模拟器上运行android应用程序。

要获取sha256/lVIcG+gpmlabsq1bW5RbvB+kqVSHKdOFyoxjo9+SLEs=,我使用了keytool -list -v -keystore sampleName.p12 -storetype PKCS12 -storepass samplePassword并将十六进制的sha256指纹转换为base64。

现在,当我尝试向服务器发送任何请求时,我会得到

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found

我显然错过了一些东西,但我不知道是什么。我还有什么需要做的吗?还是我做错了什么?还是只是不应该在本地工作?

请注意,这对我来说只是一个练习,我不会在任何真实服务器上实际部署服务器应用程序,也不会发布android应用程序。

但是我仍然会介绍该解决方案,我确实将其确定为可靠并且可以在本地工作。

1 个答案:

答案 0 :(得分:0)

CertificatePinning是常规证书检查的补充。它只会进一步限制证书的选择,因为默认情况下,您将接受主机的任何证书。

有关现有答案,请参见Adding a custom certificate to an OkHttp Client

或在这里阅读

https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CustomTrust.java

https://square.github.io/okhttp/4.x/okhttp/okhttp3/-certificate-pinner/