Android ssl:javax.net.ssl.SSLPeerUnverifiedException:没有对等证书(再次)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11923380/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:11:21  来源:igfitidea点击:

Android ssl: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate (yet again)

androidsslhttpsopenssl

提问by mvsjes2

I've got a web site that I'm enabling ssl on for a RESTful service. We have registered with RapidSSL, installed the certs, and it passes the RapidSSL checker. I'm able to access the site with various browsers, including the android browsers (built in, firefox and opera) with no problems, no warnings.

我有一个网站,我正在为 RESTful 服务启用 ssl。我们已经注册了 RapidSSL,安装了证书,并且它通过了RapidSSL 检查器。我可以使用各种浏览器访问该站点,包括 android 浏览器(内置、firefox 和 opera),没有问题,没有警告。

However, when I try to access it with my android app, I get the following exception:

但是,当我尝试使用我的 android 应用访问它时,出现以下异常:

08-11 20:04:05.586   363   381 E HttpProvider: Error executing request: No peer certificate
08-11 20:04:05.586   363   381 E HttpProvider: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:259)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:164)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
08-11 20:04:05.586   363   381 E HttpProvider:  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
08-11 20:04:05.586   363   381 E HttpProvider:  at com.xxxxx.netlib.http.HttpProvider.executeRequest(HttpProvider.java:75)

This occurs on android 2.3.3 on the emulator and on a 3.2 tablet. I've seen lots of hits on this, but nothing I've found helps me to fix the issue.

这发生在模拟器上的 android 2.3.3 和 3.2 平板电脑上。我在这方面看到了很多点击,但我发现没有任何东西可以帮助我解决这个问题。

More data:

更多数据:

$ openssl s_client -CAfile www.xxxxx.com.pem -connect www.xxxxx.com:443
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = "GeoTrust, Inc.", CN = RapidSSL CA
verify return:1
depth=0 serialNumber = 1-7wArtEjdTwJ94d5iVDooDmmC4mXyVj, OU = GT82425783, OU = See www.rapidssl.com/resources/cps (c)12, OU = Domain Control Validated - RapidSSL(R), CN = www.xxxxx.com
verify return:1
---
Certificate chain
0 s:/serialNumber=1-7wArtEjdTwJ94d5iVDooDmmC4mXyVj/OU=GT82425783/OU=See www.rapidssl.com/resources/cps (c)12/OU=Domain Control Validated - RapidSSL(R)/CN=www.xxxxx.com
  i:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
1 s:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
  i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
  i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
[snip]

The code I'm running to set up the client:

我正在运行以设置客户端的代码:

public class HttpProvider implements INetworkProvider {
  private static final String LOG = "HttpProvider";
  protected DefaultHttpClient client;

  public HttpProvider() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
    sslSocketFactory.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
    registry.register(new Scheme("https", sslSocketFactory, 443));

    client = new DefaultHttpClient(
      new ThreadSafeClientConnManager((new BasicHttpParams()), registry), new BasicHttpParams()
    );
  }
[snip]

I've also tried with STRICT_HOSTNAME_VERIFIER and still no joy.

我也试过 STRICT_HOSTNAME_VERIFIER ,但仍然没有快乐。

From what I understand I shouldn't need to set up any custom truststores or keystores since I'm registered with a recognized cert provider.

据我所知,我不需要设置任何自定义信任库或密钥库,因为我已在公认的证书提供商处注册。

I'm very new with ssl and find I'm swimming in a sea of Three Letter Acronyms, and I was hoping someone here may be able to give me a shove in the right direction.

我对 ssl 很陌生,发现我在三字母缩略词的海洋中游泳,我希望这里的某个人可以给我一个正确的方向。

采纳答案by mvsjes2

After piles of digging and experimentation, I finally realized that the url I was using had hard coded port 80 instead of defaulting to 443. Dumb dumb dumb.

经过大量的挖掘和实验,我终于意识到我使用的 url 有硬编码的 80 端口而不是默认的 443。哑哑哑巴。

The answer to this question Trusting all certificates using HttpClient over HTTPShelped tremendously for my understanding of SSL.

这个问题的答案Trusting all certificates using HttpClient over HTTPS极大地帮助了我对 SSL 的理解。