Вы можете попробовать и перенести работу в коллекцию Task
s и использовать Task.WaitAll
, чтобы присоединиться к потокам.
Вероятно, эта ссылка вам полезна: Использование Android Volley с самоподписанным SSL-сертификатом
Это может произойти по нескольким причинам, в том числе:
Официальный документ от android
Решение: вы может предоставить файл сертификата в запросе
Вероятно, эти коды ниже будут вам полезны:
1.Создайте класс HttpsTrustManager
, который реализует X509TrustManager
:
public class HttpsTrustManager implements X509TrustManager {
private static TrustManager[] trustManagers;
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}
public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return _AcceptedIssuers;
}
public static void allowAllSSL() {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[]{new HttpsTrustManager()};
}
try {
context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(context
.getSocketFactory());
}
}
2.Add HttpsTrustManager.allowAllSSL()
перед выполнением запроса https:
HttpsTrustManager.allowAllSSL();
String tag_string_req = "string_req";
StringRequest strReq = new StringRequest(Request.Method.POST,
your_https_url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "response :"+response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
}){
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("username", "max");
params.put("password", "123456");
return params;
}
};
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
Я не смог открыть ссылку, предоставленную @ Ogre_BGR, но при просмотре сети я нашел фактическую реализацию, выполненную в следующем smanikandan14 Github . Посмотрите на его объяснение SSl-соединения , чтобы узнать больше об этом.
Пока единственный ответ говорит о добавлении ненадежного сертификата в качестве решения, но поскольку ваш браузер не жалуется, обычно это означает, что Volley не может найти промежуточный сертификат, который завершает полную доверенную цепочку.
Это случилось со мной с сертификатами LetsEncrypt.
Решение Добавьте промежуточный сертификат в конфигурацию вашего веб-сервера. Для Apache вы можете следовать этой ссылке: https://access.redhat.com/solutions/43575
Для LetsEncrypt это именно этот файл: /etc/letsencrypt/live/your.website.com/chain.pem
Итак, помимо вашего CertificateFile и KeyFile у вас уже есть работа, у вас теперь есть эта третья строка:
SSLCertificateChainFile /etc/letsencrypt/live/your.website.com/chain.pem
Просто добавив эту строку, перезапуск apache и Volley больше не жалуются, и вы не вводили никаких уязвимостей в системе безопасности!
Если вы используете залп и хотите выполнить HTTPS-запрос или службу SSL-сертификации, вы можете выбрать этот самый простой способ: ->
Шаг -> 1. сохранить файл .cer в res / raw / папка.
Шаг -> 2. Используйте этот метод и замените имя файла .cer файлом .cer и замените имя своего хоста.
private SSLSocketFactory getSocketFactory() {
CertificateFactory cf = null;
try {
cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.cert_name);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.e("CERT", "ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
Log.e("CipherUsed", session.getCipherSuite());
return hostname.compareTo("10.199.89.68")==0; //The Hostname of your server.
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
SSLContext context = null;
context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
SSLSocketFactory sf = context.getSocketFactory();
return sf;
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
Шаг -> 3. Замените эту строку «RequestQueue queue = Volley.newRequestQueue (this);» с «RequestQueue queue = Volley.newRequestQueue (это новый HurlStack (null, getSocketFactory ())); по просьбе залпа.
вы можете добавить этот класс и выполнить его из метода onCreate
new NukeSSLCerts().nuke();
, он заставит залп доверять всем SSL-сертификатам.