Android的SSL:javax.net.ssl​​.SSLPeerUnverifiedException:没有对方的证书(再次)对方、证书、javax、SSL

2023-09-12 08:16:28 作者:12.Lust(渴望)

我有一个网站,我对RESTful服务启用SSL。我们已登记的RapidSSL,安装了证书,并将它传递的RapidSSL检查。我能够与各种浏览器,包括Android的浏览器没有问题(建于,Firefox和Opera),没有警告访问该站点。

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.

然而,当我试图用我的Andr​​oid应用程序访问它,我得到以下异常:

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

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)

这发生在仿真器上的Andr​​oid 2.3.3和3.2的平板电脑。我见过很多关于这个命中,但没有我发现帮助我解决这个问题。

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.

详细数据:

$ 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]

在code我运行设置客户端:

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]

我也试着与STRICT_HOSTNAME_VERIFIER和仍然没有喜悦。

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

据我了解我不应该需要设置任何自定义的信任库或密钥库,因为我注册了认可证书提供商。

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.

我很新的使用SSL,找到我游泳三个字母的缩写的海,我希望有人在这里也许能够给我推在正确的方向。

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.

推荐答案

在挖掘和实验堆,我终于明白了,我用的是URL有硬codeD 80端口,而不是默认为443哑喑哑

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.

在回答这个问题Trusting使用HttpClient的通过HTTPS 的所有证书帮助非常大我的SSL的理解。

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