android - Android 2.3 中的“无对等证书”错误,但 4 中没有

标签 android ssl

在运行 Android 2.3 但不是在 4 中的模拟器中获取 "javax.net.ssl.SSLPeerUnverifiedException: No peer certificate error"。在 4 中它可以完美运行。我正在尝试通过 https 连接到实时服务器。它使用有效的 Thawte 证书,在所有浏览器和 Android 3 和 4 中都能正常工作。

如果有人有代码帮助,请感谢。此外,如果有人对安全解决方法有任何建议,我将不胜感激。我还在学习,我已经解决这个问题一个星期了。它必须结束,这样我才能继续工作和学习。呃。

这是 HttpCLient 代码,由 Antoine Hauck (http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/) 提供:

 import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.cert.CertificateException;

    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    import javax.security.cert.X509Certificate;

    import org.apache.http.conn.ClientConnectionManager;
    import org.apache.http.conn.scheme.PlainSocketFactory;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.conn.SingleClientConnManager;

    import android.content.Context;

    public class MyHttpClient extends DefaultHttpClient {

    final Context context;

    public MyHttpClient(Context context) {
        this.context = context;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        // Register for port 443 our SSLSocketFactory with our keystore
        // to the ConnectionManager
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
         try {
             // Get an instance of the Bouncy Castle KeyStore format
             KeyStore trusted = KeyStore.getInstance("BKS");
             // Get the raw resource, which contains the keystore with
             // your trusted certificates (root and any intermediate certs)
             InputStream in = context.getResources().openRawResource(R.raw.my_cert);
             try {
                 // Initialize the keystore with the provided trusted certificates
                 // Also provide the password of the keystore
                 trusted.load(in, "my_pass".toCharArray());
             } finally {
                 in.close();
             }

            // Pass the keystore to the SSLSocketFactory. The factory is responsible
            // for the verification of the server certificate.
            SSLSocketFactory sf = new SSLSocketFactory(trusted);
            // Hostname verification from certificate
            // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
            sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

下面是实例化它的代码:

DefaultHttpClient client = new MyHttpClient(getApplicationContext());

           HttpPost post = new HttpPost(server_login_url);
           List <NameValuePair> parameters = new ArrayList <NameValuePair>();
           parameters.add(new BasicNameValuePair("username", user));
           parameters.add(new BasicNameValuePair("password", pass));

            try {
               post.setEntity(new UrlEncodedFormEntity(parameters, HTTP.UTF_8));
            } catch (UnsupportedEncodingException e2) {
                // TODO Auto-generated catch block
                Log.d(DEBUG_TAG, "in  UnsupportedEncodingException - " + e2.getMessage());
                e2.printStackTrace();
            }
                // Execute the GET call and obtain the response
           HttpResponse getResponse = null;

            try {
                getResponse = client.execute(post);
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                // Toast.makeText(getBaseContext(),message,Toast.LENGTH_LONG).show();
                Log.d(DEBUG_TAG, "in ClientProtocolException - " + e.getMessage());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                // Toast.makeText(getBaseContext(),message,Toast.LENGTH_LONG).show();
                Log.d(DEBUG_TAG, "in  client.execute IOException - " + e.getMessage());
                e.printStackTrace();
            }

错误在 IOException block 中被捕获。这是堆栈:

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:258)
org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:164)
org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
org.ffb.tools.SplashActivity$LoginTask.makeConnection(SplashActivity.java:506)
org.ffb.tools.SplashActivity$LoginTask.doLogin(SplashActivity.java:451)
org.ffb.tools.SplashActivity$LoginTask.doInBackground(SplashActivity.java:439)
org.ffb.tools.SplashActivity$LoginTask.doInBackground(SplashActivity.java:1)
android.os.AsyncTask$2.call(AsyncTask.java:185)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
java.util.concurrent.FutureTask.run(FutureTask.java:138)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
java.lang.Thread.run(Thread.java:1019)

这是链顺序(来自 openssl 命令):

我觉得链条看起来不错。

    i:/C=US/O=Thawte, Inc./OU=Domain Validated SSL/CN=Thawte DV SSL CA
  1 s:/C=US/O=Thawte, Inc./OU=Domain Validated SSL/CN=Thawte DV SSL CA
  i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized      use only/CN=thawte Primary Root CA
  2 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For      authorized use only/CN=thawte Primary Root CA
  i:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services      Division/CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com

最佳答案

这个 thread当我调试一个类似的问题时真的很有帮助。

Android 2.3 HTTPS/SSL list 摘要:

  • 如果您的 CA 在 Android 2.3 中 list of trusted CA's -- Thawte 是 -- 无需在应用中包含证书。
  • Android 2.3 不支持 Server Name Indication因此,如果您的服务器依赖它进行 SSL 握手,Android 可能无法获得您期望的证书。
  • 您是否在服务器上安装了证书链,它的顺序是否正确?大多数浏览器处理乱序证书链,但 Android 2.3 不处理。 bdc 在我上面提到的线程中的回答描述了如何使用“openssl s_client -connect yourserver.com:443”检查 SSL 证书和链的有效性。
  • 在挖掘你在底部抽屉里的那个旧的 2.3 设备时,请确保它的日期和时间设置正确。

关于android - Android 2.3 中的“无对等证书”错误,但 4 中没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9574870/

相关文章:

ssl - 如何修复以下 ansible Galaxy SSL 错误?

iOS 应用评论 : Additional files?

Android Google Drive - 文件夹更改监听器

android - 为什么我突然无法在 AS3 AIR Android 项目中使用 Firebase REST API 刷新 idToken?

java - 如何在 UI 线程中运行此类?

amazon-web-services - 在 Amazon 中部署的 Discourse 上设置 SSL

python - ./python : error while loading shared libraries: libssl. so.1.1: 无法打开共享对象文件: 没有这样的文件或目录

amazon-web-services - 使用 kops 在 AWS 上的 kubernetes 集群中自定义 SSL 证书,身份验证失败

android - SearchView.isFocused 总是返回 false

java - Android开发中的Button和Androidx.appcompat.widget.AppCompatButton有什么区别?