Ich versuche, eine https-Anfrage mit diesem Code zu stellen:
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
request = new Request<String>(Request.Method.GET,"https://devblahblahblah.com/service/etc",errListener);
aber ich erhalte diesen Fehler:
com.Android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: Java.security.cert.CertPathValidatorException: Vertrauensanker für Zertifizierungspfad nicht gefunden.
Zwei Punkte zu beachten:
Ich muss eigentlich wissen, ob es Schalter/Optionen im Android Volley-Framework gibt, mit denen ich eine HTTPS-URL erfolgreich schlagen kann?
Wahrscheinlich wird dieser Link für Sie hilfreich sein: Android Volley mit selbstsigniertem SSL-Zertifikat verwenden
Wahrscheinlich werden die folgenden Codes für Sie hilfreich sein:
1.Erstellen Sie eine HttpsTrustManager
-Klasse, die X509TrustManager
implementiert:
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. Fügen Sie HttpsTrustManager.allowAllSSL()
hinzu, bevor Sie eine https-Anfrage stellen:
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);
sie können diese Klasse hinzufügen und sie mit der onCreate
-Methode ausführen
new NukeSSLCerts().nuke();
alle SSL-Zertifikate müssen vertrauen.
Wenn Sie Volley verwenden und HTTPS-Anfragen oder einen SSL-zertifizierten Dienst wünschen, können Sie diesen einfachsten Weg wählen: ->
Schritt -> 1. Bewahren Sie die .cer-Datei im Ordner res/raw/auf.
Schritt -> 2. Verwenden Sie diese Methode und ersetzen Sie den .cer-Dateinamen durch Ihre .cer-Datei und ersetzen Sie auch Ihren Hostnamen.
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;
}
Schritt -> 3. Diese Zeile ersetzen "RequestQueue-Warteschlange = Volley.newRequestQueue (this);" mit "RequestQueue queue = Volley.newRequestQueue (dies neuer HurlStack (null, getSocketFactory ()));" auf Anfrage der Salve.
Die einzige Antwort ist bisher das Hinzufügen eines nicht vertrauenswürdigen Zertifikats als Lösung. Da Ihr Browser sich jedoch nicht beschwert, bedeutet dies normalerweise, dass Volley kein Zwischenzertifikat finden kann, das die gesamte vertrauenswürdige Kette abschließt.
Es ist mir mit LetsEncrypt-Zertifikaten passiert. Die meisten Browser verfügen bereits über Zwischenzertifikate, so dass im Browser alles gut aussieht, aber Volley hat anscheinend etwas gefehlt.
Die Lösung
Fügen Sie das Zwischenzertifikat Ihrer Webserver-Konfiguration hinzu. Für Apache können Sie dieser Referenz folgen:
https://access.redhat.com/solutions/43575
Bei LetsEncrypt handelt es sich speziell um diese Datei: /etc/letsencrypt/live/your.website.com/chain.pem
So. Neben Ihrer CertificateFile und KeyFile sollten Sie bereits arbeiten, Sie haben jetzt diese dritte Zeile:
SSLCertificateChainFile /etc/letsencrypt/live/your.website.com/chain.pem
Das Hinzufügen dieser Zeile, der Neustart von Apache und Volley beklagen sich nicht mehr und Sie haben keine Sicherheitslücken eingeführt!
Ich konnte den von @ Ogre_BGR bereitgestellten Link nicht öffnen, aber beim Durchsuchen des Netzes fand ich die eigentliche Implementierung in smanikandan14 Github . Schauen Sie sich seine SSl-Verbindungserklärung an, um mehr darüber zu erfahren.
Dies kann aus verschiedenen Gründen geschehen, darunter:
Offizielles Dokument von Android
Lösung: Sie können eine Zertifikatsdatei innerhalb der Anforderung bereitstellen
Wenn Sie auf ein solches Problem stoßen und Letsencrypt für Ihr SSL und node.js für Ihren Webserver verwenden, versuchen Sie dies. Vorausgesetzt, Sie haben so etwas. Ich habe dies durch Hinzufügen der Zeile const chain = fs ... behoben. Hoffe, das hilft
...
const app = express();
const privateKey = fs.readFileSync('ssl/privkey.pem', 'utf8');
const certificate = fs.readFileSync('ssl/cert.pem', 'utf8');
const chain = fs.readFileSync('ssl/chain.pem', 'utf8');
const credentials = {key: privateKey, cert: certificate, ca: chain};
...
var httpsServer = https.createServer(credentials, app);