2016-11-30 51 views
0

我堅持這兩天,我必須實現與客戶端證書的服務器相互身份驗證。我在res目錄下的原始文件夾中有我的.pfx文件。Https android到服務器通信總是返回403響應

我有它在res /生/ certificate.pfx

我也實施了android系統的HttpURLConnection類,並設置SSLSocketFactory的,而我從我的證件產生的一個。但問題是服務器總是返回403.我嘗試添加包括「用戶代理」在內的所有請求屬性。但似乎沒有任何工作。

我附上了下面的代碼。我相信這樣的證書。

public SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId) 
     throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException, NoSuchProviderException { 

    InputStream caInput = context.getResources().openRawResource(keystoreResId); 

    // creating a KeyStore containing trusted CAs 

    if (keyStoreType == null || keyStoreType.length() == 0) { 
     keyStoreType = KeyStore.getDefaultType(); 
    } 
    KeyStore keyStore = KeyStore.getInstance(keyStoreType); 

    keyStore.load(caInput, "".toCharArray()); 

    // creating a TrustManager that trusts the CAs in the KeyStore 

    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
    tmf.init(keyStore); 

    TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers()); 

    SSLContext sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(null, wrappedTrustManagers, null); 

    return sslContext.getSocketFactory(); 
} 

最後,在我的活動我做HTTPS調用如下

URL url = null; 
     HttpURLConnection conn; 
     try { 
      url = new URL("https://example.com"); 
      conn = (HttpURLConnection) url.openConnection(); 
      if (conn instanceof HttpsURLConnection) { 
       ((HttpsURLConnection) conn).setSSLSocketFactory(sslSocketFactory); 
      } 
      conn.setRequestMethod("GET"); 
      conn.setRequestProperty("Accept", "application/json"); 
      conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"); 

      int responseCode = conn.getResponseCode(); 
      System.out.println("Server response code" + responseCode); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

但結果始終是403禁止的。我不確定我會出錯的地方。有人請幫助我。

回答

2

啊..最後我自己發現了這個問題。我所缺少的是我加載證書後未能用密鑰存儲庫初始化我的密鑰庫工廠。

public SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId) 
     throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException, NoSuchProviderException, UnrecoverableKeyException { 

    InputStream caInput = context.getResources().openRawResource(keystoreResId); 

    // creating a KeyStore containing trusted CAs 

    if (keyStoreType == null || keyStoreType.length() == 0) { 
     keyStoreType = KeyStore.getDefaultType(); 
    } 
    KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
    keyStore.load(caInput, "".toCharArray()); 

    // creating a TrustManager that trusts the CAs in the KeyStore 

    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
    tmf.init(keyStore); 

    TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers()); 

    SSLContext sslContext = SSLContext.getInstance("TLS"); 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    kmf.init(keyStore, "".toCharArray()); 

    sslContext.init(kmf.getKeyManagers(), wrappedTrustManagers, null); 
    return sslContext.getSocketFactory(); 
} 

這些行爲我製作了訣竅。

SSLContext sslContext = SSLContext.getInstance("TLS"); 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    kmf.init(keyStore, "".toCharArray()); 

    sslContext.init(kmf.getKeyManagers(), wrappedTrustManagers, null); 

希望它能幫助別人。 :)

相關問題