【问题标题】:Volley Request over https only works with Wifi (wlan) but not for 3G/GPRS (umts)通过 https 的 Volley 请求仅适用于 Wifi (wlan),但不适用于 3G/GPRS (umts)
【发布时间】:2015-03-15 01:33:46
【问题描述】:

因为我被指示在我自己的问题中提出这个问题,所以我在这里这样做。
看到Original Topic我第一次问我的问题(现已删除)。

我遇到了同样的问题,不幸的是作者的答案没有帮助。

为了更详细地介绍我的问题,我使用 Java 8 (v8.0.25 - JDK) 在 Internet 上的 Tomcat 8 (v8.0.15) 服务器上使用自签名证书。我在那里托管我的 Java EE 应用程序,它是我的 Android 应用程序的后端。 Tomcat 的 SSL 连接器可以正常工作。当我使用 RESTClient 测试后端时,我得到了预期的结果。
我用一个证书创建了密钥库:

keytool -genkey -alias tomcat -keystore tomcat.keystore 
-storepass MYKEYSTOREPASS -keyalg RSA -keysize 2048 -validity 365

然后我提取证书:

keytool -export -alias tomcat -storepass MYKEYSTOREPASS 
-keystore tomcat.keystore -file tomcat.cer

最后,我为我的 Android 应用程序创建了一个 BKS 格式的新密钥库:

keytool -import -alias tomcat -file tomcat.cer -keypass MYKEYSTOREPASS 
-keystore tomcat.bks -storetype BKS -storepass MYKEYSTOREPASS 
-providerClass org.bouncycastle.jce.provider.BouncyCastleProvider
-providerpath $PATH_TO_BC_LIBRARY/bcprov-jdk16-146.jar

(如here 提到的“-export”和“-import”参数来自前面 发布但仍然可用。所以你也可以知道这个命令 参数为“-exportcert”和“-importcert”)

完成这些步骤后,我尝试连接,一切正常。但直到我停用/离开我的 WLAN 连接。然后它不再工作并带来“javax.net.ssl.SSLPeerUnverifiedException:没有对等证书”。
我真的不明白这种行为。

为了让 android 端更亮一点:
我以完全相同的方式使用了来自this tutorial 的类/库。

如果有什么遗漏,请评论,我会带来信息。

提前非常感谢!

【问题讨论】:

  • 你使用的是本地tomcat服务器吗?
  • 嗨 Suhail Mehta,我编辑了我的问题。
  • 您所说的“位于 www”是什么意思,是否意味着它位于您的 wifi 网络外部的某个服务器上?
  • 是的,它在我的 wifi 网络之外。 (我编辑了我的问题...)

标签: android ssl https wifi android-volley


【解决方案1】:

我认为这只是服务器配置问题。我不确定 Tomcat 是如何工作的,但它可能类似于 Apache,您在其中为“正常”请求(即非 https)声明一个虚拟主机,为 HTTPS(包括 SSL 证书)声明一个虚拟主机。通常每个虚拟主机都绑定一个 IP。很有可能当您通过 WIFI 访问服务器时,您会获得一些“内部”IP,例如 192.168.*,并且可能您将虚拟主机配置为绑定到该 IP。

当您通过 3G 访问时,您会通过“公共”网络,然后服务器的 IP 不同,因此虚拟主机不匹配,例如未使用 SSL 证书,您得到“无对等证书”。

我建议你必须检查服务器配置和日志,看看这两种方法是如何访问服务器的。

【讨论】:

  • 我通过绝对 URL 连接到我的服务器。像这样:HTTPS://aaa.bbb.ccc.ddd:8443/APP/rest/bla/foo 连接器绑定到这个端口(8443),所以每次都使用 SSL。举个例子:我从与 Android 应用程序相同 URL (HTTPS://aaa.bbb.ccc.ddd:8443/APP/rest/bla/foo) 的完全外国网络中的计算机拨打电话,我得到了我的结果。但是使用我智能手机上的 APP,它无法在 3G 上运行。我得到了你的回答,但我不确定这是否有意义。因为我的例子几乎相同,并提供了一个反例。
  • 澄清一下:您使用带有“通用名称”(FQDN) 您的 IP 或某些域/子域的自签名证书?
  • 是的,我使用自签名证书和我的服务器名称的 ip,其他元信息为空。
  • RestClient 和 Android 结果不同的唯一可能原因是 RestClient 作为浏览器插件工作,因此它使用的证书链与 android 内置的不同。这意味着您的服务器可能根本没有使用您的自签名证书。请从普通浏览器打开您的 URL 并检查使用的证书。它很有可能使用其他证书(至少在某些情况下)。
  • 顺便说一句,在自签名证书中使用 IP 不是一个好主意。回到过去,我和你现在遇到的问题完全相同,只是因为 wifi 网络使用了一些奇怪的路由,结果是服务器在某个本地 IP 上被命中(并且证书不匹配)。最好的解决方案是在证书中使用一些子域。
【解决方案2】:

在针对类似问题对 Server Fault 进行研究时,我得到了一个提示,可能还有什么问题: https://serverfault.com/questions/560733/why-isnt-tomcat-serving-the-correct-ssl-certificate 我用缺少的参数“keyAlias”试了一下,它成功了!最终解决方案 - 就像之前预期的 Ogre_BGR - 不是最佳的 tomcat 配置。连接器如下所示:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
           keystoreFile="PATH_TO_YOUR_KEYSTORE"
           keystorePass="PASSWORD_FOR_YOUR_KEYSTORE"
           keyAlias="ALIAS_OF_YOUR_CERTIFICATE"
           maxHttpHeaderSize="8192"
           />

当没有配置 keyAlias 时,Tomcat 只会静默选择它在密钥库中找到的第一个密钥。文档中提到了here(在底部)。

我希望有一天有人会很高兴阅读这篇文章,同时遇到同样的问题。

再次感谢@Ogre_BGR :)

【讨论】:

    猜你喜欢
    • 2011-07-07
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    相关资源
    最近更新 更多