Ich habe diese Methode:ändert HTTP-Post-Anfrage auf HTTPS Post Anfrage:
public static String getReportMetadata (String reportId, String sessionId, String url) throws Exception{
Map<String, Object> jsonValues = new HashMap<String, Object>();
jsonValues.put("reportID", reportId);
jsonValues.put("sessionID", sessionId);
JSONObject json = new JSONObject(jsonValues);
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url + GET_REPORT_METADATA_ACTION);
AbstractHttpEntity entity = new ByteArrayEntity(json.toString().getBytes("UTF8"));
entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(entity);
HttpResponse response = client.execute(post);
return getContent(response);
}
, die ein HTTP
Gesuch durchführt, die von-Kurs I AsyncTask
laufe unter Verwendung von Daten von dem Server zu erhalten.
Meine Frage: könnte jemand mir bitte erklären, auf einfache Art und Weise, was die Schritte sind muss ich führen diese Verbindungsart auf eine sichere Verbindung zu ändern (a.k.a mit HTTPS
). Nur von Android-Sicht (dh die Client-Anwendung).
UPDATE: Wie vorgeschlagen habe ich nur den Link zu ändern versucht und https statt http hinzufügen, aber es eine Antwort nicht zurück. Wie ich verstehe ich brauche, um ein Selbst Zeichen Zertifikat um
UPDATE2 auf Server-Seite zu verbinden zu erhalten und zu speichern: Die Lösung, die für mich funktioniert:
EasySSLSocketFactory:
public class EasySSLSocketFactory implements SocketFactory, LayeredSocketFactory {
private SSLContext sslcontext = null;
private static SSLContext createEasySSLContext() throws IOException {
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { new EasyX509TrustManager(null) }, null);
return context;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
private SSLContext getSSLContext() throws IOException {
if (this.sslcontext == null) {
this.sslcontext = createEasySSLContext();
}
return this.sslcontext;
}
/**
* @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket, java.lang.String, int,
* java.net.InetAddress, int, org.apache.http.params.HttpParams)
*/
public Socket connectSocket(Socket sock, String host, int port, InetAddress localAddress, int localPort,
HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(params);
InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
if ((localAddress != null) || (localPort > 0)) {
// we need to bind explicitly
if (localPort < 0) {
localPort = 0; // indicates "any"
}
InetSocketAddress isa = new InetSocketAddress(localAddress, localPort);
sslsock.bind(isa);
}
sslsock.connect(remoteAddress, connTimeout);
sslsock.setSoTimeout(soTimeout);
return sslsock;
}
/**
* @see org.apache.http.conn.scheme.SocketFactory#createSocket()
*/
public Socket createSocket() throws IOException {
return getSSLContext().getSocketFactory().createSocket();
}
/**
* @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
*/
public boolean isSecure(Socket socket) throws IllegalArgumentException {
return true;
}
/**
* @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, java.lang.String, int,
* boolean)
*/
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}
// -------------------------------------------------------------------
// javadoc in org.apache.http.conn.scheme.SocketFactory says :
// Both Object.equals() and Object.hashCode() must be overridden
// for the correct operation of some connection managers
// -------------------------------------------------------------------
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(EasySSLSocketFactory.class));
}
public int hashCode() {
return EasySSLSocketFactory.class.hashCode();
}
}
EasyX509TrustManager:
public class EasyX509TrustManager implements X509TrustManager {
private X509TrustManager standardTrustManager = null;
/**
* Constructor for EasyX509TrustManager.
*/
public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
super();
TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
factory.init(keystore);
TrustManager[] trustmanagers = factory.getTrustManagers();
if (trustmanagers.length == 0) {
throw new NoSuchAlgorithmException("no trust manager found");
}
this.standardTrustManager = (X509TrustManager) trustmanagers[0];
}
/**
* @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
*/
public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
standardTrustManager.checkClientTrusted(certificates, authType);
}
/**
* @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
*/
public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
if ((certificates != null) && (certificates.length == 1)) {
certificates[0].checkValidity();
} else {
standardTrustManager.checkServerTrusted(certificates, authType);
}
}
/**
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
public X509Certificate[] getAcceptedIssuers() {
return this.standardTrustManager.getAcceptedIssuers();
}
}
Und fügte ich diese Methode: getNewHttpClient()
public static HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
schließlich für jeden Platz in meinem Code, die ich hatte:
DefaultHttpClient client = new DefaultHttpClient();
Ich ersetze es mit:
HttpClient client = getNewHttpClient();
Ich bin jetzt in der Lage, die Daten von der Serverseite zu erhalten, letzte Frage ist: Ist das, was ich getan habe, sicher? oder es akzeptiert jedes selbstsignierte Zertifikat? Wenn dies der Fall ist, was sollte getan werden, um es zu ändern?
Jede Hilfe wäre willkommen.
Vielleicht hilft Ihnen Javadoc: [SchemeRegistry] (http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/scheme/SchemeRegistry.html) [SSLSocketFactory] (http: //hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLSocketFactory.html) – mleczey
Gemäß [HTTPClient SSL Guide] (htt p: //hc.apache.org/httpclient-legacy/sslguide.html), das einzige, was Sie tun müssen, ist "https: //" in Ihre URL-Zeichenfolge einzugeben. Dadurch erhalten Sie eine HTTPS-Verbindung mit einer Browser-äquivalenten Authentifizierungsebene (d. H. Eine beliebige von mehreren hundert Zertifizierungsstellen kann das Serverzertifikat signieren). Die 'SchemeRegistry' und' SSLSocketFactory' spielen nur dann eine Rolle, wenn Sie die SSL-Behandlung anpassen möchten, typischerweise um SSL-Pinning zu implementieren (dh eine stärkere Authentizitätsbeschränkung verwenden). Schauen Sie sich Moxies Github für einen guten (LGPL lizensierten) Android ssl pinner an. – Barend
@Barend, ich habe versucht, nur den Link zu ändern und https anstelle von http hinzufügen, aber es gibt keine Antwort zurück. Soweit ich weiß, muss ich ein Self-Sign-Zertifikat beschaffen und speichern, um eine Verbindung zur Serverseite herzustellen. –