2013-08-08 18 views
26

Có hàng tá bài đăng về vấn đề này (javax.net.ssl.SSLPeerUnverifiedException: Không có chứng chỉ ngang hàng) nhưng tôi chưa tìm thấy bất kỳ thứ gì phù hợp với mình.Sửa lỗi an toàn: javax.net.ssl.SSLPeerUnverifiedException: Không có chứng chỉ ngang hàng

Nhiều bài đăng (như thisthis) "giải quyết" điều này bằng cách cho phép tất cả chứng chỉ được chấp nhận nhưng, tất nhiên, đây không phải là giải pháp tốt cho bất cứ điều gì ngoài thử nghiệm.

Những người khác có vẻ khá bản địa hóa và không hoạt động đối với tôi. Tôi thực sự hy vọng rằng ai đó có một số hiểu biết sâu sắc mà tôi thiếu.

Vì vậy, vấn đề của tôi: Tôi đang thử nghiệm trên một máy chủ chỉ có thể truy cập thông qua mạng cục bộ, kết nối qua HTTPS. Thực hiện cuộc gọi mà tôi cần thông qua trình duyệt hoạt động tốt. Không phàn nàn về chứng chỉ và nếu bạn kiểm tra các chứng chỉ, tất cả sẽ tốt.

Khi tôi thử trên thiết bị Android của tôi, tôi nhận được javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

Dưới đây là đoạn code mà gọi đó là:

StringBuilder builder = new StringBuilder(); 
builder.append(/* stuff goes here*/); 

httpGet.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
ResponseHandler<String> responseHandler = new BasicResponseHandler(); 

// Execute HTTP Post Request. Response body returned as a string 
HttpClient httpClient = MyActivity.getHttpClient(); 
HttpGet httpGet = new HttpGet(builder.toString()); 

String jsonResponse = httpClient.execute(httpGet, responseHandler); //Line causing the Exception 

Mã của tôi cho MyActivity.getHttpClient():

protected synchronized static HttpClient getHttpClient(){ 
    if (httpClient != null) 
     return httpClient; 

    HttpParams httpParameters = new BasicHttpParams(); 
    HttpConnectionParams.setConnectionTimeout(httpParameters, TIMEOUT_CONNECTION); 
    HttpConnectionParams.setSoTimeout(httpParameters, TIMEOUT_SOCKET); 
    HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1); 

    //Thread safe in case various AsyncTasks try to access it concurrently 
    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); 
    ClientConnectionManager cm = new ThreadSafeClientConnManager(httpParameters, schemeRegistry); 

    httpClient = new DefaultHttpClient(cm, httpParameters); 

    CookieStore cookieStore = httpClient.getCookieStore(); 
    HttpContext localContext = new BasicHttpContext(); 
    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); 

    return httpClient; 
} 

Bất kỳ trợ giúp sẽ được nhiều đánh giá cao.

Sửa

Cũng chỉ đề cập đến Tôi đã có vấn đề SSL khác với ứng dụng khác nhưng thêm phần SchemeRegistry cố định nó cho tôi trước.

Chỉnh sửa 2

Cho đến nay tôi đã chỉ được thử nghiệm trên Android 3.1, nhưng tôi cần điều này để làm việc trên Android 2.2+ không phân biệt. Tôi vừa thử nghiệm trên trình duyệt trên tab Android của mình (Android 3.1) và nó phàn nàn về chứng chỉ. Đó là tốt trên trình duyệt máy tính của tôi, nhưng không phải trên trình duyệt Android hoặc trong ứng dụng của tôi.

Sửa 3

Hóa ra trình duyệt iOS cũng phàn nàn về nó. Tôi bắt đầu nghĩ rằng đó là một vấn đề chuỗi chứng chỉ mô tả ở đây (SSL certificate is not trusted - on mobile only)

+0

vấn đề này do https m i right ?? –

+0

Có, tôi đang kết nối qua https. Tôi sẽ cập nhật câu hỏi –

+0

Hãy thử điều này: https://stackoverflow.com/a/38598593/2301721 – ashishdhiman2007

Trả lời

5

Hãy thử mã dưới đây: -

 BasicHttpResponse httpResponse = null; 

     HttpPost httppost = new HttpPost(URL); 

     HttpParams httpParameters = new BasicHttpParams(); 
     // Set the timeout in milliseconds until a connection is 
     // established. 
     int timeoutConnection = ConstantLib.CONNECTION_TIMEOUT; 
     HttpConnectionParams.setConnectionTimeout(httpParameters, 
       timeoutConnection); 
     // Set the default socket timeout (SO_TIMEOUT) 
     // in milliseconds which is the timeout for waiting for data. 
     int timeoutSocket = ConstantLib.CONNECTION_TIMEOUT; 
     HttpConnectionParams 
       .setSoTimeout(httpParameters, timeoutSocket); 

     DefaultHttpClient httpClient = new DefaultHttpClient(
       httpParameters); 
     List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); 
     nameValuePairs.add(new BasicNameValuePair(ConstantLib.locale, 
       locale)); 
+1

Chỉ cần thử nó, mặc dù sử dụng một HttpGet và nó vẫn xảy ra –

+0

Nhưng nó là wrks cho tôi –

+4

Cool. Tôi có các ứng dụng hoạt động trên https đối với tôi nhưng không phải lúc này, đó là lý do tôi đặt câu hỏi –

4

Trong trường hợp của tôi tất cả mọi thứ đã từng làm việc tốt. Đột nhiên sau 2 ngày, thiết bị của tôi không hiển thị bất kỳ liên kết trang web hoặc hình ảnh https nào.

Sau một số điều tra, hóa ra cài đặt Thời gian của tôi không được cập nhật trên thiết bị.

Tôi đã thay đổi cài đặt thời gian của mình đúng cách và nó hoạt động.

0

Tôi đã có ngoại lệ này khi tôi sử dụng chứng chỉ tự ký + địa chỉ ip. Chỉ cần thêm những dòng này

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

và HttpURLConnection của bạn sẽ hoạt động. Bí quyết đó không liên quan đến việc xác thực chống lại CA! Vì vậy, nếu tôi chỉ định sai CA và sử dụng thủ thuật đó, tôi sẽ nhận được một ngoại lệ khác. Vì vậy, những gì còn lại chủ tin cậy

Chỉ trong trường hợp, tôi sẽ để lại mã cho định CA của riêng bạn ở đây:

String certStr = context.getString(R.string.caApi); 
X509Certificate ca = SecurityHelper.readCert(certStr); 

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
ks.load(null); 
ks.setCertificateEntry("caCert", ca); 

tmf.init(ks); 

SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(null, tmf.getTrustManagers(), null); 
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 

Đừng quên sử dụng buildTypes tính năng thú vị và đặt CA khác nhau cho debug/release trong thư mục res .