android - 在 android 2.3 设备上没有对等证书错误,但在 android 4+ 上工作正常

标签 android ssl https ssl-certificate

  1. 我已经为我的服务器证书创建了 bks 文件。这是在原始文件夹中的项目源代码中添加的

  2. 我已经创建了我的 https 客户端,如下所示:

    公共(public)类 MyHttpsClient 扩展 DefaultHttpClient {

    final Context context;
    
    public MyHttpsClient(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.mykeystore);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Also provide the password of the keystore
                trusted.load(in, "testpassword".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);
        }
    }
    

  3. 然后我像这样使用它:

    DefaultHttpClient httpClient = new MyHttpsClient(context);
    HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 30000);
    HttpContext localContext = new BasicHttpContext();
    HttpPost httpPost = new HttpPost(url);
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-type", "application/json");
    httpPost.setEntity(new StringEntity(jsonString));
    
    response = httpClient.execute(httpPost, localContext);
    HttpEntity entity = response.getEntity();
    httpresponse = getResponse(entity);
    
  4. 有趣的部分来了。这在 android 4+ 真实设备和模拟器上工作得很好。这在 android 2.3 上失败了

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

如果没有已知的“信任所有证书”方式,我如何让它在 android 2.3 上运行?

最佳答案

几天后我解决了同样的问题。解决方案如下。我将所有安装在设备上的证书(在我的例子中是三星 galaxy II)交给服务器端开发人员,他们管理安装在服务器上的证书链。他分析了 ssl 链,发现链中有一个证书(Thawte 2006)和其他证书(Thawte 2010)。他删除了 2006 年颁发的最旧证书,并且 android 2.x 上的 ssl 验证开始工作。我建议您,在尝试使用本地 keystore 之前,研究您的服务器端 ssl 链并检查该链是否没有不必要的证书,因为 android 2.x 设备不能忽略不必要的证书,但其他平台 3.x 4x 和ios,windows phone 可以做到,我的意思是忽略 ssl 证书链中的“垃圾”。

关于android - 在 android 2.3 设备上没有对等证书错误,但在 android 4+ 上工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26679740/

相关文章:

android - 当用户停止拖动时在 Material Slider 中显示标签 [KOTLIN]

Python线程挂了?

web-services - 如何在 websphere 5 的 web 服务客户端中配置 jks 证书

javascript - 为什么 Safari 无法通过 https 播放 HTML5 音频?

java - 使用 Tomcat 和 Android 进行相互认证

java - HttpClient ssl 和 login.facebook.com

android - 为什么我无法在 Android Studio 中显示 URL 中的图像?

android - 构建大小大于 100 Mb 的 android 应用程序

java - 如何更改Android中的Fragment

node.js - 将 Heroku 应用程序连接到 Atlas MongoDB 云服务