Najpierw musiałem przyznać, że wiem, że akceptowanie wszystkich certyfikatów może być uznane za pozbawione zabezpieczeń. Mamy "prawdziwe" certyfikaty, ale tylko na naszych systemach live. Certyfikaty w naszych systemach testowych są z podpisem własnym. Tak długo, jak się rozwijamy, musimy używać serwerów testowych, co zmusza mnie do rodzaju wyłączania certyfikatów.akceptuj samopodpisane certyfikaty SSL-> gdzie ustawić domyślny TrustManager
Widziałem wiele rzeczy tutaj na Stackoverflow i w całym Internecie, które próbują zrobić to samo: Akceptowanie certyfikatów SSL. Jednak żadna z tych odpowiedzi nie wydaje się dotyczyć mojego problemu, ponieważ nie mam problemu z HTTPSUrlConnections
.
Jeśli robię żądanie kodu zazwyczaj wygląda następująco (skomentował dla clearification):
//creates an HTTP-Post with an URL
HttpPost post = createBaseHttpPost();
//loads the request Data inside the httpPost
post.setEntity(getHttpPostEntity());
//appends some Headers like user-agend or Request UUIDs
appendHeaders(post);
HttpClient client = new DefaultHttpClient();
//mResponse is a custom Object which is returned
//from the custom ResponseHandler(mResponseHandler)
mResponse = client.execute(post, mResponseHandler);
return mResponse;
czytałem że należy wstrzykiwać własne TrustManager
i X509HostnameVerivier
. Stworzyłem je tak:
private static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
}
};
private static X509HostnameVerifier ACCEPT_ALL_HOSTNAMES =
new X509HostnameVerifier() {
public void verify(String host, String[] cns, String[] subjectAlts)
throws SSLException {
}
public void verify(String host, X509Certificate cert) throws SSLException {
}
public void verify(String host, SSLSocket ssl) throws IOException {
}
public boolean verify(String host, SSLSession session) {
return true;
}
};
Gdybym wstrzyknąć HostnameVerifier
wewnątrz moją prośbę tak (klient jest DefaultHttpClient z góry)
SSLSocketFactory ssl = (SSLSocketFactory)client.getConnectionManager().getSchemeRegistry().getScheme("https").getSocketFactory();
ssl.setHostnameVerifier(ACCEPT_ALL_HOSTNAMES);
odpowiedź odwraca się od „hosta ** nie pasuje” na "Złą prośbę". Domyślam się, że muszę ustawić TrustManager, ale nie mam bladego pojęcia, gdzie ustawić go wewnątrz mojej prośby, ponieważ nie używam HttpsUrlConnections wspomnianych wszędzie, gdzie go szukałem.
Zamiast dodawać kod, który zezwala na każdy certyfikat (to jest kod, który może nigdy nie zostać usunięty, zwłaszcza jeśli zapomnisz o tym, gdy nadejdzie termin), możesz rozważyć uruchomienie własnego przetestuj CA. Trzeba będzie zaimportować ten testowy certyfikat CA do magazynu zaufanych certyfikatów, ale jest to bardziej realistyczny test, w tym nazwy hostów (i mniej podatny na pozostawienie złego kodu w wydanym produkcie). Istnieją narzędzia, które ułatwiają zarządzanie małymi urzędami certyfikacji. – Bruno