【问题标题】:Android: Making Https RequestAndroid:发出 Https 请求
【发布时间】:2023-03-26 06:26:01
【问题描述】:

在发出 Https 请求时,如何避免“javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常和 Android Apache lib 间隙“构造函数 SSLSocketFactory(SSLContext) 未定义”?

【问题讨论】:

  • 我有一个适合我的答案。我会在我的 8 小时时间限制到期后的某个时间发布它。来吧 Stack Overflow,让我回答我自己的问题!
  • 您首先需要更多积分 :) 这是我的贡献。
  • 仅供参考,截至撰写本文时(02/2013),此错误似乎已融入某些 HTC 手机固件

标签: android apache https


【解决方案1】:

我有类似的问题,更像是question,但根本原因与两个问题中提到的完全不同。

我使用 DefaultHttpClient 作为 httpclient 来请求 https://maps.googleapis.com 之类的链接。我正在尝试所有提议的解决方案,但没有一个对我有用。经过几个小时试图解决它,找到了根本原因:我的设备连接到一个访客 WIFI,它可能有一些特定的过滤规则阻止了相关的网络部分。切换到其他网络解决了我的问题。

【讨论】:

    【解决方案2】:

    此方法接受一个 HttpClient 实例并返回一个准备好 https 的 HttpClient 实例。

     private HttpClient sslClient(HttpClient client) {
        try {
            X509TrustManager tm = new X509TrustManager() { 
                public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
                }
    
                public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
                }
    
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory ssf = new MySSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = client.getConnectionManager();
            SchemeRegistry sr = ccm.getSchemeRegistry();
            sr.register(new Scheme("https", ssf, 443));
            return new DefaultHttpClient(ccm, client.getParams());
        } catch (Exception ex) {
            return null;
        }
    }
    

    由于Android org.apache.http.conn.ssl.SSLSocketFactory 没有SSLSocketFactory(SSLContext) 构造函数,所以我将类扩展如下。

     public class MySSLSocketFactory extends SSLSocketFactory {
         SSLContext sslContext = SSLContext.getInstance("TLS");
    
         public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
             super(truststore);
    
             TrustManager tm = new X509TrustManager() {
                 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                 }
    
                 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                 }
    
                 public X509Certificate[] getAcceptedIssuers() {
                     return null;
                 }
             };
    
             sslContext.init(null, new TrustManager[] { tm }, null);
         }
    
         public MySSLSocketFactory(SSLContext context) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
            super(null);
            sslContext = context;
         }
    
         @Override
         public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
             return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
         }
    
         @Override
         public Socket createSocket() throws IOException {
             return sslContext.getSocketFactory().createSocket();
         }
    }
    

    优秀文章在这里:http://javaskeleton.blogspot.com/2010/07/avoiding-peer-not-authenticated-with.html

    还有一些帮助:Trusting all certificates using HttpClient over HTTPS

    【讨论】:

    • 老兄,太棒了!这对我帮助很大!
    • 谢谢,如果没有你的帮助,我真的会迷路的!请注意实现此答案的其他人:请注意您已包含 org.apache.http.conn.ssl.SSLSocketFactory,而不是 javax.net.ssl.SSLSocketFactory。它们不同且不兼容。
    • 请记住,从安全角度来看,使用无操作 TrustManagerALLOW_ALL_HOSTNAME_VERIFIER 是非常值得怀疑的。如果目标是连接到测试环境,很好,但请不要将此代码投入生产。
    • super(null); 行出现错误,表示 构造函数 SSLSocketFactory(KeyStore) 不明确。
    • @ThinkChris 尝试将该 null 转换为 SSLContext 实例。超级((SSLContext) null);
    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 2016-04-29
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 2023-03-22
    • 2021-10-06
    相关资源
    最近更新 更多