【问题标题】:Untrusted certificate error and httpclient on androidAndroid上的不受信任的证书错误和httpclient
【发布时间】:2011-07-05 04:59:08
【问题描述】:

我正在使用 Apache HttpClient 库来设置 https 连接。不幸的是,Android 给了我一个“不可信的服务器证书”错误。如果我使用手机的浏览器浏览该站点,它会正确验证证书,这让我相信我需要让 HttpClient“知道”手机上的根证书。这是我的 HttpClient 设置代码:

HttpParams params = new BasicHttpParams();

HttpConnectionParams.setConnectionTimeout( params, 20000 );
HttpConnectionParams.setSoTimeout( params, 20000 );

HttpProtocolParams.setVersion( params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset( params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue( params, false);

SchemeRegistry schReg = new SchemeRegistry();
schReg.register( new Scheme( "http", PlainSocketFactory.getSocketFactory(), 80 ) );
schReg.register( new Scheme( "https", SSLSocketFactory.getSocketFactory(), 443 ) );

ClientConnectionManager conMgr = new ThreadSafeClientConnManager( params, schReg );

DefaultHttpClient defaultHttpClient = new DefaultHttpClient( conMgr, params );

return ( defaultHttpClient );

如您所见,我对 SSLSocketFactory 没有做任何特别的事情。如何在不在密钥库中添加自定义证书的情况下使 HttpClient 库验证我的站点?我应该创建一个自定义 SSLSocketFactory 并从 Android 手机加载 cacerts.bks 吗?在那种情况下,我可能会遇到不同手机上密钥库的不同密码的问题?

如果您需要更多信息,请告诉我。这 SSL 东西对我来说很难。

【问题讨论】:

  • 我使用 HttpClient 访问 HTTPS 没有问题。我只是在使用 BasicHttpParams 和 DefaultHttpClient,ClientConnectionManager 或 SchemeRegistry 都没有……对你来说有必要吗?
  • 证书需要验证。不推荐安装“无检查”TrustManager,否则使用 ssl 的意义何在?我想确定我正在连接到正确的主机并且证书没有经过修改。不过感谢您的链接。
  • 在查看博客、java 代码和 android 源代码一周后,发现问题出在我连接的站点上的 ssl 证书的排序上。因此,如果您遇到证书验证问题,请务必仔细检查证书是否以正确的顺序呈现给您,以及根证书是否存在于 android 设备上!

标签: android ssl https keystore


【解决方案1】:

我相信您的证书不包含验证系统可信根证书路径所需的所有中间证书。一些 SSL 配置验证工具可能会将其报告为不完整的证书链

证书可以包含一个特殊的授权信息访问扩展 (RFC-3280),其中包含指向颁发者证书的 URL。大多数浏览器可以使用 AIA 扩展来下载缺少的中间证书以完成证书链。但是一些客户端(移动浏览器、OpenSSL)不支持这个扩展,所以他们报告这样的证书不受信任。

您可以通过将证书中的所有证书连接到受信任的根证书(不包括,按此顺序)手动解决证书链不完整问题,以防止此类问题。请注意,受信任的根证书不应该存在,因为它已经包含在系统的根证书存储中。

您应该能够从颁发者那里获取中间证书并自己将它们连接在一起。我编写了一个脚本来自动执行该过程,它遍历 AIA 扩展以生成正确链接证书的输出。 https://github.com/zakjan/cert-chain-resolver

【讨论】:

  • 感谢您的评论,您的工具最终帮助我解决了问题。
【解决方案2】:

跟进 zakjan 的回答,当我尝试使用 jquery 在我的新安全服务器上(在 android webview 中)执行 AJAX 请求时遇到问题。它在浏览器中有效,但在我的应用程序中无效。

我用过这个网站:https://certificatechain.io/

我粘贴了我从 Comodo (positiveSSL) 返回的已签名 .crt 文件的文本,它给了我所需的所有内容的连接。我将其保存为我的域 +“chain.crt”(见下文)

然后,在我的 apache 配置中,我为那个特定的虚拟主机输入了这样的内容:

SSLEngine On
SSLCertificateFile /etc/ssl/localcerts/example_com.crt
SSLCertificateKeyFile /etc/ssl/localcerts/example.com.key
SSLCACertificateFile /etc/ssl/localcerts/example.com.chain.crt

之后,我的 Android 应用程序的 webview 使用 ajax POST 到我的服务器没有问题。我在 2 台真实设备上进行了尝试,一台运行 2.3.4,一台运行 4.something。并在运行 2.3 的模拟器上。一切正常。

我希望这会有所帮助。

【讨论】:

    【解决方案3】:

    我以前也有同样的问题..

    你可以使用这个答案,它对我很有效..

    Trusting all certificates using HttpClient over HTTPS

    【讨论】:

    • 不要在生产环境中这样做!您正在关闭所有 SSL 保护。这应该只用于内部测试。任何人都可以 MITM 您的请求并窃取所有敏感信息。
    • 我想补充一点,现在谷歌拒绝所有试图绕过这一步的应用
    猜你喜欢
    • 2015-02-14
    • 2015-01-24
    • 2021-12-10
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 2012-07-05
    相关资源
    最近更新 更多