Закрепление SSL с помощью Google Volley
Я начинаю свой вопрос с упоминания того, что я пробовал до сих пор:
У меня нет сертификата в моем приложении, я использую только ключ 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. так что это также дает вышеуказанную ошибку.
Я пробовал это с CertificatePinner OKHttp, это также не работает для меня. Та же ошибка Я также попытался передать 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.
1 ответ
Используйте этот 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);
}
}
}