10

我提一下我迄今試圖開始我的問題:SSL鋼釘使用谷歌凌空

我沒有在我的應用程序的證書,我使用SHA256鍵而已,大部分互聯網上的答案需要物理證書在應用程序中加載它在密鑰庫中,我沒有。

我收到以下錯誤:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 

1)TrustKit它不需要編譯SDK 24及以上,但我有23和許多支持庫都與SDK 23同步,所以我不能改變這一切他們,它可能會在某個時候崩潰我的應用程序。

2)CWAC-NetSecurity我已經在我的代碼中實現了這個功能,但沒有使用Android N安全設置,我也遵循git頁面給出的指令,但無法將sslSocketfactory從它傳遞給Volley,它有OkHTTP示例。所以它也給出了上述錯誤。

我已經用OKHttp的CertificatePinner試過了,它也不適合我。同樣的錯誤。我也嘗試將hostNameVerifier和sslSocketFactory傳遞給HttpsUrlConnection,但是發生同樣的錯誤。

JsonObjectRequestSolaire jsonRequest = new JsonObjectRequestSolaire(method, URL, object, headers, responseListener, errorListener); 
    RetryPolicy policy = new DefaultRetryPolicy(TIMEOUT, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 
    jsonRequest.setRetryPolicy(policy); 
    jsonRequest.setShouldCache(false); 

    OkHttpClient okHttpClient = new OkHttpClient.Builder() 
      .certificatePinner(new CertificatePinner.Builder() 
        .add("my_domain", "sha256/shaKey")//example.com 
        .add("my_domain", "sha256/shaKey")//also tried *.example.com 
        .build()) 
      .build(); 

    //HttpsURLConnection.setDefaultHostnameVerifier(okHttpClient.hostnameVerifier()); 
    //HttpsURLConnection.setDefaultSSLSocketFactory(okHttpClient.sslSocketFactory()); 

    RequestQueue requestQueue = Volley.newRequestQueue(activity.getApplicationContext(), new HurlStack(null, okHttpClient.sslSocketFactory())); 
    requestQueue.add(jsonRequest); 

通過使用trustKit我們的iOS人員實施,它是爲他工作。

在此先感謝。

請在這裏分享您的寶貴意見,以便我能理解這個SSL固定概念。

+0

是所用的服務器證書是否有效?固定意味着定期檢查證書+固定根,中間或離開證書。順便說一句:如果你有sha256散列和域名,你可以簡單地從服務器上下載證書來驗證它是否是正確的。 – Robert

+0

也請查看[此鏈接](http://blog.ostorlab.co/2016/05/ssl-pinning-in-android-networking.html)。 –

+0

也檢查[this](https://developer.android.com/training/articles/security-ssl.html#CommonProblems),可能是CA的問題。 –

回答

3

使用此VolleySingleton:

public class VolleySingleton { 


    private static VolleySingleton mInstance; 
    private RequestQueue mRequestQueue; 
    private static Context mCtx; 

    private VolleySingleton(Context context) { 
    mCtx = context; 
    mRequestQueue = getRequestQueue(); 
    } 

    public static synchronized VolleySingleton getInstance(Context context) { 
    if (mInstance == null) { 
     mInstance = new VolleySingleton(context); 
    } 
    return mInstance; 
    } 

    public RequestQueue getRequestQueue() { 
    if (mRequestQueue == null) { 
     // getApplicationContext() is key, it keeps you from leaking the 
     // Activity or BroadcastReceiver if someone passes one in. 
     mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(), new HurlStack(null, newSslSocketFactory())); 
    } 
    return mRequestQueue; 
    } 

    public <T> void addToRequestQueue(Request<T> req) { 
    int socketTimeout = 90000; 
    RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, 
     DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
     DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 
    req.setRetryPolicy(policy); 
    getRequestQueue().add(req); 
    } 

    private SSLSocketFactory newSslSocketFactory() { 
    try { 
     // Get an instance of the Bouncy Castle KeyStore format 
     KeyStore trusted = KeyStore.getInstance("BKS"); 
     // Get the raw resource, which contains the keystore with 
     // your trusted certificates (root and any intermediate certs) 
     InputStream in = mCtx.getApplicationContext().getResources().openRawResource(R.raw.trusted); 
     try { 
     // Initialize the keystore with the provided trusted certificates 
     // Provide the password of the keystore 
     trusted.load(in, mCtx.getString(R.string.KEYSTORE_PASS).toCharArray()); 
     } finally { 
     in.close(); 
     } 

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

     SSLContext context = SSLContext.getInstance("TLSv1.2"); 
     context.init(null, tmf.getTrustManagers(), null); 

     HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { 
     @Override 
     public boolean verify(String hostname, SSLSession session) { 
      Log.i("Volley","Verifing host:"+hostname); 
      return true; 
     } 
     }); 

     SSLSocketFactory sf = context.getSocketFactory(); 
     return sf; 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 
    } 
}