2016-11-30 190 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); 

希望它能帮助别人。 :)

相关问题