【问题标题】:SSL certificate expired in android app but not in pc/mobile browsersSSL 证书在 Android 应用程序中过期,但在 PC/移动浏览器中未过期
【发布时间】:2015-11-16 18:22:46
【问题描述】:

所以这是一个奇怪的情况。我有一个在 https 上运行的网站。我在 android 上也有一个应用程序,它利用这个网站进行休息 API 调用。直到现在一切都运行良好。最近我的主人改变了一些东西,一切都崩溃了。当我从浏览器发出休息请求时,它工作正常。但是当我使用该应用程序执行此操作时,它不起作用,并且出现此异常:

javax.net.ssl.SSLHandshakeException: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: 无法验证证书:证书于 2014 年 8 月 21 日星期四 06:03:34 EDT 过期(与 2015 年 8 月 22 日星期六 17:41:59 EDT 相比) 在 com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java

但在电脑上一切正常,我仔细检查了证书将于 2016 年到期。

所以我更进一步,尝试浏览我的网站,我得到了一些有趣的结果。在 300 个浏览器中,我在其中几个中遇到了同样的问题。

http://i.stack.imgur.com/d86tE.png
http://oi60.tinypic.com/30ml1n4.jpg

我现在在安装 SSL 时在我的主机中收到此警告。

"注意:您没有专用 IP 地址。因此,不支持 SNI 的 Web 浏览器可能会在您的用户访问您的任何 SSL 网站时向他们发出虚假的安全警告。Microsoft® Internet Explorer™ on Windows XP™ 是最广泛使用的不支持 SNI 的网络浏览器。”

我不能 100% 确定这个警告是否更早出现,但我只是想把各个部分放在一起。

代码没有问题,因为我手机上的应用程序已经停止工作,而之前工作的。

【问题讨论】:

    标签: ssl https certificate


    【解决方案1】:

    Server Name Indication (SNI) 表示客户端(浏览器、应用程序)在 SSL/TLS 握手中发送预期的主机名。这类似于 Host HTTP 标头,并且可以让具有不同主机名的多个虚拟服务器共享相同的 IP 地址。 如果您的客户端不支持 SNI,服务器将发送回一些默认证书或触发 SSL/TLS 握手错误。

    所有现代浏览器都支持 SNI,但旧版浏览器或 XP 上的 IE8 等平台不支持 SNI。此外,Android SDK does not support SNI 附带的 Apache HTTP 请求库可能是您的问题。

    到目前为止一切正常。最近我的宿主改变了一些东西,一切都崩溃了。

    我猜这是不完全更改的结果。看起来使用 SNI 的客户端的证书已被更新版本替换,因为之前的证书已过期。但是站点的默认证书,即用于非 SNI 客户端的证书,仍然是旧的过期证书。因此,您会在所有使用 SNI 的客户端上获得有效证书,但在所有无法执行 SNI 的客户端上都会出现过期错误。

    【讨论】:

    • 谢谢!不知道android不支持SNI。我现在 100% 确定这是问题所在。所以我得到了主机的 IP 地址并检查了它的证书。原来它过期了。它与我在我的 android 应用程序中获得的过期证书相同。
    【解决方案2】:

    我在从我的 Android 应用程序调用第三方 API 时遇到了同样的问题。 为了解决这个问题,我使用了 javax.net.ssl 包中的 HttpsURLConnection 类,它支持 SNI。

    执行 API 调用的示例。

    import javax.net.ssl.HttpsURLConnection;
    import java.net.URL;
    
    public void performApiCall() {
        try {
                URL url = new URL("https://yourdestination.com");
                HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
                connection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
                connection.setRequestMethod("POST");
    
                // other stuffs like adding parameters etc. Used android.util.Pair.
    
                connection.connect();
    
                // you can read response based on connection.getResponseCode()
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 2014-10-14
      • 2016-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多