2010-08-09 17 views
12

Tôi đang sử dụng KSOAP2 để quản lý SOAP trong Android nhưng nó sử dụng https cho url SOAP và tôi nhận được lỗi này: javax.net.ssl.SSLException: Chứng chỉ máy chủ không đáng tin cậy
Lỗi bình thường vì chứng chỉ không đáng tin cậy, nhưng bất kỳ ai biết cách giải quyết lỗi này? Tôi không thể quản lý chứng chỉ vì đến từ một công ty khác và tôi không có quyền truy cập để thay đổi chứng chỉ.KSOAP 2 Android với HTTPS

Cảm ơn

Trả lời

10

Tôi chưa thể nhận xét nên tôi đăng nhận xét của mình lên rallat trả lời tại đây. Giải pháp của ông hoạt động nhưng nó cần giải thích thêm. Để chạy ksoap2 với ssl:

  1. Đặt ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar trong một dự án
  2. nguồn Tải ksoap2 từ https://github.com/mosabua/ksoap2-android/tree/ (kho ksoap2)
  3. Sao chép HttpTransportSE.java, ServiceConnectionSE.java (Tôi cũng cần thiết để sao chép Transport.java, ServiceConnection.javaHeaderProperty.java).Xóa hàng nhập khẩu từ các tập tin và chắc chắn rằng họ sử dụng tập tin của bạn (không phải hàng nhập khẩu từ ksoap2.jar)
  4. Sử dụng rallat câu trả lời (tôi copy-dán nó):

    • ServiceConnectionSE.java thêm này cho chấp nhận chứng chỉ tin cậy:

      private TrustManager[] trustAllCerts = new TrustManager[] { 
          new X509TrustManager() { 
           public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
            return null; 
           } 
           public void checkClientTrusted(
            java.security.cert.X509Certificate[] certs, String authType) { 
           } 
           public void checkServerTrusted(
            java.security.cert.X509Certificate[] certs, String authType) { 
           } 
          } 
      }; 
      
    • sau đó sử dụng nhà thầu này để phép chứng chỉ không tin cậy và không hostname xác nhận:

      public ServiceConnectionSE(String url) throws IOException { 
          try { 
           SSLContext sc = SSLContext.getInstance("TLS"); 
           sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
           HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
          } catch (Exception e) { 
           e.getMessage(); 
          } 
          connection = (HttpsURLConnection) new URL(url).openConnection(); 
          ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); 
      }  
      
    • Second contructor

      public ServiceConnectionSE(Proxy proxy, String url) throws IOException { 
          try { 
           SSLContext sc = SSLContext.getInstance("TLS"); 
           sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
           HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
          } catch (Exception e) { 
           e.getMessage(); 
          } 
          connection = (HttpsURLConnection) new URL(url).openConnection(); 
          ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); 
      
          connection.setUseCaches(false); 
          connection.setDoOutput(true); 
          connection.setDoInput(true); 
      } 
      
  5. Trong code của bạn chỉ cần sử dụng:

    HttpTransportSE aht = new HttpTransportSE(URL);  
    aht.call(SOAP_ACTION, envelope); 
    

Những vấn đề khác như trong hướng dẫn

+1

@Zirael ... Cảm ơn bạn đã anwser ur nó đã giúp ... Tôi đã háo hức muốn biết hơn là làm việc xung quanh nếu có chứng chỉ bảo mật ... Làm thế nào để tôi tiến xa hơn với nó ..? –

+0

Không thể tìm thấy nguồn gốc của ksoap bằng liên kết được cung cấp - liên kết bị hỏng. = \ cập nhật: Tôi đã tìm thấy nó ... chỉ cần sử dụng: https: //github.com/mosabua/ksoap2-android/ – micyunu

4

tôi tìm ra câu trả lời bằng bản thân mình

  • trên ServiceConnectionSE.java thêm này cho chấp nhận chứng chỉ tin cậy:

    private TrustManager[] trustAllCerts = new TrustManager[]{ 
        new X509TrustManager() { 
         public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
          return null; 
         } 
         public void checkClientTrusted(
          java.security.cert.X509Certificate[] certs, String authType) { 
         } 
         public void checkServerTrusted(
          java.security.cert.X509Certificate[] certs, String authType) { 
         } 
        } 
    }; 
    
  • sau đó trong các nhà xây dựng thêm này để cho phép không tin cậy chứng chỉ và không phải tên máy chủ được xác minh:

    try { 
         SSLContext sc = SSLContext.getInstance("TLS"); 
         sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
         HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
        } catch (Exception e) { 
         e.getMessage(); 
        } 
        connection = (HttpsURLConnection) new URL(url).openConnection(); 
        ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); 
    
3

Tạo một lớp mới FakeX509TrustManager để xử lý các vấn đề chứng chỉ,

FakeX509TrustManager.allowAllSSL(); 
    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 

Lớp tạo mới là như sau:

public class FakeX509TrustManager implements X509TrustManager { 

    private static TrustManager[] trustManagers; 
    private static final X509Certificate[] _AcceptedIssuers = new 
X509Certificate[] {}; 

    @Override 
    public void checkClientTrusted(X509Certificate[] chain, String 
authType) throws CertificateException { 
    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] chain, String 
authType) throws CertificateException { 
    } 

    public boolean isClientTrusted(X509Certificate[] chain) { 
      return true; 
    } 

    public boolean isServerTrusted(X509Certificate[] chain) { 
      return true; 
    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
      return _AcceptedIssuers; 
    } 

    public static void allowAllSSL() { 
      HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() 
{ 
        @Override 
        public boolean verify(String hostname, SSLSession session) { 
          return true; 
        } 

      }); 

      SSLContext context = null; 
      if (trustManagers == null) { 
        trustManagers = new TrustManager[] { new FakeX509TrustManager() }; 
      } 

      try { 
        context = SSLContext.getInstance("TLS"); 
        context.init(null, trustManagers, new SecureRandom()); 
      } catch (NoSuchAlgorithmException e) { 
        e.printStackTrace(); 
      } catch (KeyManagementException e) { 
        e.printStackTrace(); 
      } 

     HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); 
    } 

} 
+0

Nghiêm trọng +1 jowett ... Tôi đặt mã của bạn vào cuối hoạt động của tôi và tất cả những gì tôi có để làm là làm cho FakeX509TrustManager tĩnh và nó có quyền thông qua ... Tôi đã đọc nhiều hơn một vài bài viết SO và điều này là dễ nhất để thực hiện cho đến nay. Chú ý ngày tháng trên các câu trả lời trước trong bài này ... đủ nói. Bạn có bất kỳ tài nguyên nào trên cách dễ nhất để KHÔNG tin tưởng tất cả các chứng chỉ về mã sản xuất không? – whyoz

+0

@whyoz xin lỗi, không có tài nguyên. – jowett

11

Kiểm tra lại vấn đề này, tôi đã khám phá ra một giải pháp sạch hơn đối với tôi. Không cần sửa đổi tệp KSOAP2.

Trong dự án của bạn, liên kết ksoap2-android-assembly-3.0.0-jar, không có sửa đổi.

Tiếp theo, tạo một file có tên SSLConnection.java với mã này:

package com.example.mypackage; 

import android.util.Log; 

import javax.net.ssl.HostnameVerifier; 
import javax.net.ssl.SSLSession; 
import javax.net.ssl.TrustManager; 
import java.security.KeyManagementException; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 

public class SSLConection { 

    private static TrustManager[] trustManagers; 

    public static class _FakeX509TrustManager implements javax.net.ssl.X509TrustManager { 
     private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{}; 

     public void checkClientTrusted(X509Certificate[] arg0, String arg1) 
       throws CertificateException { 
     } 

     public void checkServerTrusted(X509Certificate[] arg0, String arg1) 
       throws CertificateException { 
     } 

     public X509Certificate[] getAcceptedIssuers() { 
      return (_AcceptedIssuers); 
     } 
    } 

    public static void allowAllSSL() { 

     javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { 
      @Override 
      public boolean verify(String hostname, SSLSession session) { 
       return true; 
      } 
     }); 

     javax.net.ssl.SSLContext context; 

     if (trustManagers == null) { 
      trustManagers = new TrustManager[]{new _FakeX509TrustManager()}; 
     } 

     try { 
      context = javax.net.ssl.SSLContext.getInstance("TLS"); 
      context.init(null, trustManagers, new SecureRandom()); 
      javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); 
     } catch (NoSuchAlgorithmException e) { 
      Log.e("allowAllSSL", e.toString()); 
     } catch (KeyManagementException e) { 
      Log.e("allowAllSSL", e.toString()); 
     } 
    } 
} 

Và chỉ cần gọi đến SSLConection.allowAllSSL(); trước khi gọi một phương pháp máy chủ thông qua KSOAP2. Đó là tất cả, làm việc cho tôi. Tất cả các chứng chỉ SSL đều được chấp nhận và tôi có thể sử dụng KSOAP2 với giao thức https.

+0

Cảm ơn bạn đã thêm đoạn mã của mình quá – rallat

+0

Giải pháp đơn giản hoàn hảo! Cảm ơn bạn :) – OmarBizreh

+0

rất vui được trợ giúp! :-) – Neonigma

Các vấn đề liên quan