问题描述
我试图做一个简单的HTTPGET阅读的网页。我有这个工作在iOS和工作在Android上通过HTTP,而不是HTTPS。
该网址是一个内网IP和自定义端口,这样我就可以用HTTP这样写使用 HTTP的路径:// IP地址:端口/的mypage.html
HttpClient的HttpClient的=新DefaultHttpClient(httpParameters);
HTT presponse响应;
字符串responseString = NULL;
尝试 {
//尝试连接
HTTPGET GET =新HTTPGET(PARAMS [0]。路径);
get.addHeader(授权,
基本
+ Base64.en codeBytes(新的String(PARAMS [0] .username +:+参数[0]。密码)
.getBytes()));
响应= httpclient.execute(获得);
状态行状态行= response.getStatusLine();
如果(statusLine.getStatus code()== HttpStatus.SC_OK){
ByteArrayOutputStream OUT =新ByteArrayOutputStream();
。response.getEntity()的writeTo(出);
out.close();
responseString = out.toString();
} 其他 {
//关闭连接。
。response.getEntity()的getContent()close()方法。
抛出新IOException异常(statusLine.getReasonPhrase());
}
}赶上(ClientProtocolException E){
Log.e(TAG,ClientProtocolException);
this.e = E;
}赶上(IOException异常E){
Log.e(TAG,IOException异常);
this.e = E;
}
返回responseString;
当我尝试使用https,我得到的没有对方的证书
错误。所以我用这个code曾尝试: HttpClient的HttpClient的=新DefaultHttpClient(httpParameters);
私人HttpClient的createHttpClient(){
尝试 {
密钥库的trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(NULL,NULL);
SSLSocketFactory的SF =新MySSLSocketFactory(的trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
的HttpParams PARAMS =新BasicHttpParams();
HttpProtocolParams.setVersion(参数,可以HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(参数,可以HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(参数,可以真正的);
SchemeRegistry schReg =新SchemeRegistry();
schReg.register(新计划(HTTP,PlainSocketFactory.getSocketFactory(),80));
schReg.register(新计划(https开头,SF,8080));
ClientConnectionManager conMgr =新ThreadSafeClientConnManager(参数,可以schReg);
返回新DefaultHttpClient(conMgr,则params);
}赶上(例外五){
返回新DefaultHttpClient();
}
}
但是这给了我一个连接被对方关闭
错误。
我是什么做错了吗?我可以放心地忽略证书,因为这是自签名的证书的内部网络,但是我无法控制的VERT和我的应用程序的用户可能具有不同的证书,所以我真的需要自动接受或绕过它。
感谢
编辑------------------------------
在尝试下面我-NAME IS的答案:我创建了一个CustomX509TrustManager类的建议,然后使用它像这样创建一个自定义的HttpClient:
私人HttpClient的sslClient(HttpClient的客户端){
尝试 {
CustomX509TrustManager TM =新CustomX509TrustManager();
的SSLContext CTX = SSLContext.getInstance(TLS);
ctx.init(空,新的TrustManager [] {} TM,NULL);
SSLSocketFactory的SSF =新MySSLSocketFactory(CTX);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager CCM = client.getConnectionManager();
SchemeRegistry SR = ccm.getSchemeRegistry();
sr.register(新计划(https开头,社保基金,8080));
返回新DefaultHttpClient(CCM,client.getParams());
}赶上(例外前){
返回null;
}
}
和最后使用HttpClient的是这样的:
私有类httpGETTask扩展的AsyncTask< getParams能够,太虚,字符串> {
私人异常E = NULL;
@覆盖
保护字符串doInBackground(getParams能够... PARAMS){
//设置连接参数
的HttpParams httpParameters =新BasicHttpParams();
INT timeoutConnection = 15000;
HttpConnectionParams.setConnectionTimeout(httpParameters,timeoutConnection);
INT timeoutSocket = 15000;
HttpConnectionParams.setSoTimeout(httpParameters,timeoutSocket);
Log.v(TAG,则params [0]。路径);
HttpClient的HttpClient的=新DefaultHttpClient(httpParameters);
HttpClient的= sslClient(HttpClient的);
HTT presponse响应;
字符串responseString = NULL;
尝试 {
//尝试连接
HTTPGET GET =新HTTPGET(PARAMS [0]。路径);
get.addHeader(授权,
基本
+ Base64.en codeBytes(新的String(PARAMS [0] .username +:+参数[0]。密码)
.getBytes()));
响应= httpclient.execute(获得);
状态行状态行= response.getStatusLine();
如果(statusLine.getStatus code()== HttpStatus.SC_OK){
ByteArrayOutputStream OUT =新ByteArrayOutputStream();
。response.getEntity()的writeTo(出);
out.close();
responseString = out.toString();
} 其他 {
//关闭连接。
。response.getEntity()的getContent()close()方法。
抛出新IOException异常(statusLine.getReasonPhrase());
}
}赶上(ClientProtocolException E){
Log.e(TAG,ClientProtocolException);
this.e = E;
}赶上(IOException异常E){
Log.e(TAG,IOException异常);
this.e = E;
}
返回responseString;
记录的路径的格式为的https:// IP地址:8080 / page.html即可
但我得到一个连接关闭由对
错误:
下面的来源应该解决您的问题。
进口android.app.Activity;
进口android.widget.EditText;
进口android.os.Bundle;
进口org.apache.http.Htt presponse;
进口org.apache.http.Header
进口的java.io.InputStream;
进口java.io.BufferedReader中;
进口java.io.InputStreamReader中;
进口android.util.Log;
进口android.view.Menu;
公共类MainActivity延伸活动{
私人的EditText文本;
@覆盖
公共无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_main);
文=(EditText上)findViewById(R.id.editText1);
连接();
}
私人无效连接(){
尝试 {
的DataLoader DL =新的DataLoader();
字符串URL =HTTPS:// IP地址;
HTT presponse响应= dl.secureLoadData(URL);
StringBuilder的SB =新的StringBuilder();
sb.append(头:\ñ\ N);
标题[]头= response.getAllHeaders();
的for(int i = 0; I< headers.length;我++){
标题H =头[I]
。sb.append(h.getName())追加(:\ t的)附加(h.getValue())追加(\ N);
}
InputStream的是= response.getEntity()的getContent()。
StringBuilder的出=新的StringBuilder();
的BufferedReader BR =新的BufferedReader(新InputStreamReader的(是));
对(串线= br.readLine(!);行= NULL;行= br.readLine())
out.append(线);
br.close();
sb.append(\ñ\ nCONTENT:\ñ\ N)。追加(out.toString());
Log.i(回应,sb.toString());
text.setText(sb.toString());
}赶上(例外五){
e.printStackTrace();
}
}
@覆盖
公共布尔onCreateOptionsMenu(功能菜单){
。getMenuInflater()膨胀(R.menu.activity_main,菜单);
返回true;
}
}
进口android.app.Application;
进口android.content.Context;
进口的java.io.InputStream;
公共类MeaApplication扩展应用{
私有静态上下文的背景下;
@覆盖
公共无效的onCreate(){
super.onCreate();
MeaApplication.context = getApplicationContext();
}
公共静态上下文getAppContext(){
返回MeaApplication.context;
}
公共静态的InputStream loadCertAsInputStream(){
返回MeaApplication.context.getResources()。openRawResource(
R.raw.meacert);
}
}
进口org.apache.http.conn.ssl.SSLSocketFactory;
进口javax.net.ssl.SSLContext;
进口java.security.KeyStore中;
进口java.security.NoSuchAlgorithmException;
进口java.security.KeyManagementException;
进口java.security.KeyStoreException;
进口java.security.UnrecoverableKeyException;
进口javax.net.ssl.TrustManager;
进口的java.net.Socket;
进口java.io.IOException异常;
进口的java.net.UnknownHostException;
/ **
http://janis.peisenieks.lv/en/76/english-making-an-ssl-connection-via-android/:*来自
*
* /
公共类CustomSSLSocketFactory扩展的SSLSocketFactory {
的SSL连接的SSL连接= SSLContext.getInstance(TLS);
公共CustomSSLSocketFactory(密钥库信任库)
抛出抛出:NoSuchAlgorithmException,KeyManagementException,
KeyStoreException,UnrecoverableKeyException {
超(信任库);
的TrustManager TM =新CustomX509TrustManager();
sslContext.init(空,新的TrustManager [] {} TM,NULL);
}
公共CustomSSLSocketFactory(的SSL连接上下文)
抛出KeyManagementException,抛出:NoSuchAlgorithmException,
KeyStoreException,UnrecoverableKeyException {
超(空);
的SSLContext =背景;
}
@覆盖
公共插座中的createSocket(Socket套接字,字符串主机,INT端口,
布尔自动关闭)抛出IOException异常,UnknownHostException异常{
返回sslContext.getSocketFactory()中的createSocket(插座,主机,端口,
自动关闭);
}
@覆盖
公共插座中的createSocket()抛出IOException异常{
返回sslContext.getSocketFactory()中的createSocket()。
}
}
进口javax.net.ssl.X509TrustManager;
进口java.security.cert.CertificateException;
进口java.security.cert.X509Certificate;
进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.security.cert.CertificateFactory;
公共类CustomX509TrustManager实现X509TrustManager {
@覆盖
公共无效checkClientTrusted(x509证书[]链,字符串的authType)
抛出CertificateException {
}
@覆盖
公共无效checkServerTrusted(java.security.cert.X509Certificate []证书,
字符串的authType)抛出CertificateException {
//在这里,您可以验证服务器证书。 (如对一其存储在移动装置)
//的InputStream inStream中= NULL;
// 尝试 {
// inStream中= MeaApplication.loadCertAsInputStream();
// CertificateFactory CF = CertificateFactory.getInstance(X.509);
// x509证书CA =(x509证书)
// cf.generateCertificate(inStream中);
// inStream.close();
//
//为(x509证书的证书:证书){
// // Verifing通过公钥
// cert.verify(ca.getPublicKey());
//}
//}赶上(例外五){
//抛出新抛出:IllegalArgumentException(不受信任的证书!);
// } 最后 {
// 尝试 {
// inStream.close();
//}赶上(IOException异常E){
// e.printStackTrace();
//}
//}
}
公共x509证书[] getAcceptedIssuers(){
返回null;
}
}
进口org.apache.http.Htt presponse;
进口org.apache.http.client.ClientProtocolException;
进口java.io.IOException异常;
进口java.security.NoSuchAlgorithmException;
进口java.security.KeyManagementException;
进口java.net.URISyntaxException;
进口java.security.KeyStoreException;
进口java.security.UnrecoverableKeyException;
进口javax.net.ssl.SSLContext;
进口javax.net.ssl.TrustManager;
进口java.security.SecureRandom中;
进口org.apache.http.client.HttpClient;
进口org.apache.http.impl.client.DefaultHttpClient;
进口org.apache.http.conn.ssl.SSLSocketFactory;
进口org.apache.http.conn.ClientConnectionManager;
进口org.apache.http.conn.scheme.Scheme;
进口org.apache.http.conn.scheme.SchemeRegistry;
进口org.apache.http.client.methods.HttpGet;
公共类的DataLoader {
公众的Htt presponse secureLoadData(字符串URL)
抛出ClientProtocolException,IOException异常,
抛出:NoSuchAlgorithmException,KeyManagementException,
的URISyntaxException,KeyStoreException,UnrecoverableKeyException {
的SSLContext CTX = SSLContext.getInstance(TLS);
ctx.init(空,新的TrustManager [] {新CustomX509TrustManager()},
新的SecureRandom());
HttpClient的客户端=新DefaultHttpClient();
SSLSocketFactory的SSF =新CustomSSLSocketFactory(CTX);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager CCM = client.getConnectionManager();
SchemeRegistry SR = ccm.getSchemeRegistry();
sr.register(新计划(https开头,社保基金,443));
DefaultHttpClient sslClient =新DefaultHttpClient(CCM,
client.getParams());
HTTPGET GET =新HTTPGET(新的URI(URL));
HTT presponse响应= sslClient.execute(获得);
返回响应;
}
}
I am trying to do a simple HttpGet to read a webpage. I have this working on iOS and working on Android over http, but not https.
The url is an internal network IP and custom port, so I can read with http like this using a path of http://ipaddress:port/MyPage.html
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpResponse response;
String responseString = null;
try {
// Try connection
HttpGet get = new HttpGet(params[0].path);
get.addHeader("Authorization",
"Basic "
+ Base64.encodeBytes(new String(params[0].username + ":" + params[0].password)
.getBytes()));
response = httpclient.execute(get);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
// Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.e(TAG, "ClientProtocolException");
this.e = e;
} catch (IOException e) {
Log.e(TAG, "IOException");
this.e = e;
}
return responseString;
When I try using https, I get the No peer certificate
error. So I have tried using this code:HttpClient httpclient = new DefaultHttpClient(httpParameters);
private HttpClient createHttpClient() {
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.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https", sf, 8080));
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
return new DefaultHttpClient(conMgr, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
but this gives me a Connection closed by peer
error.
What am I doing wrong? I can safely ignore the certificate, as it's an internal network with self signed cert, however I have no control over the vert and users of my app may have different certs, so I really need to auto accept or bypass it.
Thanks
EDIT ------------------------------
After trying My-Name-Is answer below:I've created a CustomX509TrustManager class as suggested, then create a custom HttpClient using it like this:
private HttpClient sslClient(HttpClient client) {
try {
CustomX509TrustManager tm = new CustomX509TrustManager();
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new MySSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = client.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", ssf, 8080));
return new DefaultHttpClient(ccm, client.getParams());
} catch (Exception ex) {
return null;
}
}
And finally use this HttpClient like this:
private class httpGETTask extends AsyncTask<GetParams, Void, String> {
private Exception e = null;
@Override
protected String doInBackground(GetParams... params) {
// Set connection parameters
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 15000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 15000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
Log.v(TAG, params[0].path);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
httpclient = sslClient(httpclient);
HttpResponse response;
String responseString = null;
try {
// Try connection
HttpGet get = new HttpGet(params[0].path);
get.addHeader("Authorization",
"Basic "
+ Base64.encodeBytes(new String(params[0].username + ":" + params[0].password)
.getBytes()));
response = httpclient.execute(get);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
// Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.e(TAG, "ClientProtocolException");
this.e = e;
} catch (IOException e) {
Log.e(TAG, "IOException");
this.e = e;
}
return responseString;
The logged path is in the format https://ipaddress:8080/Page.html
But I get a Connection closed By Peer
error:
The following source should fix your problem.
import android.app.Activity;
import android.widget.EditText;
import android.os.Bundle;
import org.apache.http.HttpResponse;
import org.apache.http.Header
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
private EditText text;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (EditText) findViewById(R.id.editText1);
connect();
}
private void connect(){
try {
DataLoader dl = new DataLoader();
String url = "https://IpAddress";
HttpResponse response = dl.secureLoadData(url);
StringBuilder sb = new StringBuilder();
sb.append("HEADERS:\n\n");
Header[] headers = response.getAllHeaders();
for (int i = 0; i < headers.length; i++) {
Header h = headers[i];
sb.append(h.getName()).append(":\t").append(h.getValue()).append("\n");
}
InputStream is = response.getEntity().getContent();
StringBuilder out = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
for (String line = br.readLine(); line != null; line = br.readLine())
out.append(line);
br.close();
sb.append("\n\nCONTENT:\n\n").append(out.toString());
Log.i("response", sb.toString());
text.setText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
import android.app.Application;
import android.content.Context;
import java.io.InputStream;
public class MeaApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
MeaApplication.context = getApplicationContext();
}
public static Context getAppContext() {
return MeaApplication.context;
}
public static InputStream loadCertAsInputStream() {
return MeaApplication.context.getResources().openRawResource(
R.raw.meacert);
}
}
import org.apache.http.conn.ssl.SSLSocketFactory;
import javax.net.ssl.SSLContext;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import javax.net.ssl.TrustManager;
import java.net.Socket;
import java.io.IOException;
import java.net.UnknownHostException;
/**
* Taken from: http://janis.peisenieks.lv/en/76/english-making-an-ssl-connection-via-android/
*
*/
public class CustomSSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public CustomSSLSocketFactory(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new CustomX509TrustManager();
sslContext.init(null, new TrustManager[] { tm }, null);
}
public CustomSSLSocketFactory(SSLContext context)
throws KeyManagementException, NoSuchAlgorithmException,
KeyStoreException, UnrecoverableKeyException {
super(null);
sslContext = context;
}
@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port,
autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateFactory;
public class CustomX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType) throws CertificateException {
// Here you can verify the servers certificate. (e.g. against one which is stored on mobile device)
// InputStream inStream = null;
// try {
// inStream = MeaApplication.loadCertAsInputStream();
// CertificateFactory cf = CertificateFactory.getInstance("X.509");
// X509Certificate ca = (X509Certificate)
// cf.generateCertificate(inStream);
// inStream.close();
//
// for (X509Certificate cert : certs) {
// // Verifing by public key
// cert.verify(ca.getPublicKey());
// }
// } catch (Exception e) {
// throw new IllegalArgumentException("Untrusted Certificate!");
// } finally {
// try {
// inStream.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.KeyManagementException;
import java.net.URISyntaxException;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.security.SecureRandom;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.client.methods.HttpGet;
public class DataLoader {
public HttpResponse secureLoadData(String url)
throws ClientProtocolException, IOException,
NoSuchAlgorithmException, KeyManagementException,
URISyntaxException, KeyStoreException, UnrecoverableKeyException {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[] { new CustomX509TrustManager() },
new SecureRandom());
HttpClient client = new DefaultHttpClient();
SSLSocketFactory ssf = new CustomSSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = client.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", ssf, 443));
DefaultHttpClient sslClient = new DefaultHttpClient(ccm,
client.getParams());
HttpGet get = new HttpGet(new URI(url));
HttpResponse response = sslClient.execute(get);
return response;
}
}
这篇关于Android的SSL HTTPGET(没有同行证书)错误,或者(连接由同行关闭)错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!