赞
踩
- package com.example.photocrop;
-
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
-
- import org.apache.http.HttpResponse;
- import org.apache.http.HttpStatus;
- import org.apache.http.StatusLine;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.client.methods.HttpUriRequest;
-
- import android.app.Activity;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.os.AsyncTask.Status;
- import android.text.TextUtils;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
-
- public class MainActivity extends Activity {
- private Button httpsButton;
- private TextView conTextView;
-
- private CreateHttpsConnTask httpsTask;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- httpsButton = (Button) findViewById(R.id.create_https_button);
- httpsButton.setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(View v) {
- runHttpsConnection();
- }
- });
-
- conTextView = (TextView) findViewById(R.id.content_textview);
- conTextView.setText("初始为空");
- }
-
- private void runHttpsConnection() {
- if (httpsTask == null || httpsTask.getStatus() == Status.FINISHED) {
- httpsTask = new CreateHttpsConnTask();
- httpsTask.execute();
- }
- }
-
- private class CreateHttpsConnTask extends AsyncTask<Void, Void, Void> {
- private static final String HTTPS_EXAMPLE_URL = "自定义";
- private StringBuffer sBuffer = new StringBuffer();
-
- @Override
- protected Void doInBackground(Void... params) {
- HttpUriRequest request = new HttpPost(HTTPS_EXAMPLE_URL);
- HttpClient httpClient = HttpUtils.getHttpsClient();
- try {
- HttpResponse httpResponse = httpClient.execute(request);
- if (httpResponse != null) {
- StatusLine statusLine = httpResponse.getStatusLine();
- if (statusLine != null
- && statusLine.getStatusCode() == HttpStatus.SC_OK) {
- BufferedReader reader = null;
- try {
- reader = new BufferedReader(new InputStreamReader(
- httpResponse.getEntity().getContent(),
- "UTF-8"));
- String line = null;
- while ((line = reader.readLine()) != null) {
- sBuffer.append(line);
- }
-
- } catch (Exception e) {
- Log.e("https", e.getMessage());
- } finally {
- if (reader != null) {
- reader.close();
- reader = null;
- }
- }
- }
- }
-
- } catch (Exception e) {
- Log.e("https", e.getMessage());
- } finally {
-
- }
-
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- if (!TextUtils.isEmpty(sBuffer.toString())) {
- conTextView.setText(sBuffer.toString());
- }
- }
-
- }
- }
HttpUtils.java
- package com.example.photocrop;
-
- import org.apache.http.HttpVersion;
- import org.apache.http.client.HttpClient;
- import org.apache.http.conn.ClientConnectionManager;
- import org.apache.http.conn.scheme.PlainSocketFactory;
- import org.apache.http.conn.scheme.Scheme;
- import org.apache.http.conn.scheme.SchemeRegistry;
- import org.apache.http.conn.ssl.SSLSocketFactory;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
- import org.apache.http.params.BasicHttpParams;
- import org.apache.http.params.HttpProtocolParams;
- import org.apache.http.protocol.HTTP;
-
- import android.content.Context;
-
-
- public class HttpUtils {
- public static HttpClient getHttpsClient() {
- <span style="white-space:pre"> </span>HttpClient mHttpsClient = new DefaultHttpClient();
- <span style="white-space:pre"> </span>SSLSocketFactory mSSLSocketFactory = SSLSocketFactory.getSocketFactory();
- <span style="white-space:pre"> </span>if (mSSLSocketFactory != null) {
- <span style="white-space:pre"> </span>Scheme mScheme = new Scheme("https", mSSLSocketFactory, 443);
- <span style="white-space:pre"> </span>mHttpsClient.getConnectionManager().getSchemeRegistry().register(mScheme);
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>return mHttpsClient;
- }
- }
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <Button
- android:id="@+id/create_https_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello_world"
- android:textSize="16sp" />
-
- <TextView
- android:id="@+id/content_textview"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:textSize="16sp" />
-
- </LinearLayout>
schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
加入对HTTPS的支持,就可以有效的建立HTTPS连接了,例如“https://www.google.com.hk”了,但是访问自己基于Nginx搭建的HTTPS服务器却不行,因为它使用了不被系统承认的自定义证书,会报出如下问题:No peer certificate。
package com.example.photocrop;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.SSLSocketFactory;
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port,
autoClose);
}
public static SSLSocketFactory getSocketFactory() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory factory = new MySSLSocketFactory(trustStore);
return factory;
} catch (Exception e) {
e.getMessage();
return null;
}
}
}
同时,需要修改DefaultHttpClient的register方法,改为自己构建的sslsocket:
public static HttpClient getCustomClient() {
BasicHttpParams 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", MySSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager connMgr = new ThreadSafeClientConnManager(params, schReg);
return new DefaultHttpClient(connMgr, params);
}
这样就可以成功的访问自己构建的基于Nginx的HTTPS虚拟站点了。
要验证自定义证书,首先要把证书编译到应用中,这需要使用keytool工具生产KeyStore文件。这里的证书就是指目标服务器的公钥,可以从web服务器配置的.crt文件或.pem文件获得。同时,你需要配置bouncycastle,我下载的是bcprov-jdk16-145.jar,至于配置大家自行google就好了。
keytool -importcert -v -trustcacerts -alias example -file www.example.com.crt -keystore example.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath /home/wzy/Downloads/java/jdk1.7.0_60/jre/lib/ext/bcprov-jdk16-145.jar -storepass pw123456
运行后将显示证书内容并提示你是否确认,输入Y回车即可。
生产KeyStore文件成功后,将其放在app应用的res/raw目录下即可。
- package com.example.photocrop;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.security.KeyManagementException;
- import java.security.KeyStore;
- import java.security.KeyStoreException;
- import java.security.NoSuchAlgorithmException;
- import java.security.UnrecoverableKeyException;
-
- import org.apache.http.conn.ssl.SSLSocketFactory;
-
- import android.content.Context;
-
- public class CustomerSocketFactory extends SSLSocketFactory {
-
- private static final String PASSWD = "pw123456";
-
- public CustomerSocketFactory(KeyStore truststore)
- throws NoSuchAlgorithmException, KeyManagementException,
- KeyStoreException, UnrecoverableKeyException {
- super(truststore);
- }
-
- public static SSLSocketFactory getSocketFactory(Context context) {
- InputStream input = null;
- try {
- input = context.getResources().openRawResource(R.raw.example);
- KeyStore trustStore = KeyStore.getInstance(KeyStore
- .getDefaultType());
-
- trustStore.load(input, PASSWD.toCharArray());
-
- SSLSocketFactory factory = new CustomerSocketFactory(trustStore);
-
- return factory;
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- } finally {
- if (input != null) {
- try {
- input.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- input = null;
- }
- }
- }
-
- }
同时,需要修改DefaultHttpClient的register方法,改为自己构建的sslsocket:
- public static HttpClient getSpecialKeyStoreClient(Context context) {
- BasicHttpParams 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", CustomerSocketFactory.getSocketFactory(context), 443));
-
- ClientConnectionManager connMgr = new ThreadSafeClientConnManager(params, schReg);
-
- return new DefaultHttpClient(connMgr, params);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。