android中进行https连接的方式

如果不需要验证服务器端证书,直接照这里做

public class Demo extends Activity {
	/** Called when the activity is first created. */
	private TextView text;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		text = (TextView) findViewById(R.id.text);
		GetHttps();
	}
	private void GetHttps() {
		String https = " https://800wen.com/";
		try {
			SSLContext sc = SSLContext.getInstance("TLS");
			sc.init(null, new TrustManager[] { new MyTrustManager() }, new SecureRandom());
			HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
			HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());
			HttpsURLConnection conn = (HttpsURLConnection) new URL(https).openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.connect();
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			StringBuffer sb = new StringBuffer();
			String line;
			while ((line = br.readLine()) != null)
				sb.append(line);
			text.setText(sb.toString());
		} catch (Exception e) {
			Log.e(this.getClass().getName(), e.getMessage());
		}
	}
	private class MyHostnameVerifier implements HostnameVerifier {
		@Override
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}
	private class MyTrustManager implements X509TrustManager {
		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}
		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}
		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	}
}

如果需要验证服务器端证书(这样能够防钓鱼),我是这样做的,还有些问题问大牛:
    a. 导出公钥。在浏览器上用https访问tomcat,查看其证书,并另存为一个文件(存成了X.509格式:xxxx.cer)
    b. 导入公钥。把xxxx.cer放在Android的assets文件夹中,以方便在运行时通过代码读取此证书,留了两个问题给大牛:

AssetManager am = context.getAssets();  
InputStream ins = am.open("robusoft.cer");  
try {  
        //读取证书  
        CertificateFactory cerFactory = CertificateFactory.getInstance("X.509");  //问1  
        Certificate cer = cerFactory.generateCertificate(ins);  
        //创建一个证书库,并将证书导入证书库  
        KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");   //问2  
        keyStore.load(null, null);  
        keyStore.setCertificateEntry("trust", cer);  
        return keyStore;  
} finally {  
        ins.close();  
}  
//把咱的证书库作为信任证书库  
SSLSocketFactory socketFactory = new SSLSocketFactory(keystore);  
Scheme sch = new Scheme("https", socketFactory, 443);  
//完工  
HttpClient mHttpClient = new DefaultHttpClient();  
mHttpClient.getConnectionManager().getSchemeRegistry().register(sch);


问1:这里用"PKCS12"不行
答1:PKCS12和JKS是keystore的type,不是Certificate的type,所以X.509不能用PKCS12代替


问2:这里用"JKS"不行。
答2:android平台上支持的keystore type好像只有PKCS12,不支持JKS,所以不能用JKS代替在PKCS12,不过在windows平台上是可以代替的


----------------------------------------------分割线-------------------------------------------------------------------------

1。数据通信时加密,不同平台加密后的结果不同,用的库不同吧(进行相应的修改比较麻烦)


2。采用https,系统自动做好了,简单一些


https与http的通信,在我看来主要的区别在于https多了一个安全验证机制,而Android采用的是X509验证,首先我们需要这重写X509类,建立我们的验证规则、、不过对于特定的项目,我们一般都是无条件信任服务端的,因此我们可以对任何证书都无条件信任(其实本质上我们只是信任了特定url的证书,为了偷懒,才那么选择的)

/**
 *信任所有主机-对于任何证书都不做检查   
 */   
class MytmArray implements X509TrustManager {   
    public X509Certificate[] getAcceptedIssuers() {   
        // return null;   
        return new X509Certificate[] {};   
    }   
  
    @Override  
    public void checkClientTrusted(X509Certificate[] chain, String authType)   
            throws CertificateException {   
        // TODO Auto-generated method stub   
  
    }   
  
    @Override  
    public void checkServerTrusted(X509Certificate[] chain, String authType)   
            throws CertificateException {   
        // TODO Auto-generated method stub   
        // System.out.println("cert: " + chain[0].toString() + ", authType: "   
        // + authType);   
    }   
};  

 好了,我们写好了信任规则,接下载就要创建一个主机的信任列表

 static TrustManager[] xtmArray = new MytmArray[] { new MytmArray() };   
  
    /**  
     * 信任所有主机-对于任何证书都不做检查  
     */  
    private static void trustAllHosts() {   
        // Create a trust manager that does not validate certificate chains   
        // Android 采用X509的证书信息机制   
        // Install the all-trusting trust manager   
        try {   
            SSLContext sc = SSLContext.getInstance("TLS");   
            sc.init(null, xtmArray, new java.security.SecureRandom());   
            HttpsURLConnection   
                    .setDefaultSSLSocketFactory(sc.getSocketFactory());   
            // HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);//   
            // 不进行主机名确认   
        } catch (Exception e) {   
            e.printStackTrace();   
        }   
    }   
  
    static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {   
        @Override  
        public boolean verify(String hostname, SSLSession session) {   
            // TODO Auto-generated method stub   
            // System.out.println("Warning: URL Host: " + hostname + " vs. "   
            // + session.getPeerHost());   
            return true;   
        }   
    };


上面的都是https通信需要做的几个基本要求,接下载我们要做的就是https的使用啦下面就以get和post为例进行说明,中间还涉及到cookie的使用

String httpUrl="XXXXX"  
String result = "";   
        HttpURLConnection http = null;   
        URL url;   
        try {   
            url = new URL(httpUrl);   
            // 判断是http请求还是https请求   
            if (url.getProtocol().toLowerCase().equals("https")) {   
                trustAllHosts();   
                http = (HttpsURLConnection) url.openConnection();   
                ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认   
  
            } else {   
                http = (HttpURLConnection) url.openConnection();   
            }   
            http.setConnectTimeout(10000);// 设置超时时间   
            http.setReadTimeout(50000);   
            http.setRequestMethod("GET");// 设置请求类型为   
            http.setDoInput(true);   
            http.setRequestProperty("Content-Type", "text/xml");   
//http.getResponseCode());http或https返回状态200还是403   
BufferedReader in = null;   
            if (obj.getHttpStatus() == 200) {   
                getCookie(http);   
                in = new BufferedReader(new InputStreamReader(   
                        http.getInputStream()));   
            } else  
                in = new BufferedReader(new InputStreamReader(   
                        http.getErrorStream()));   
            result = in.readLine();   
            Log.i("result", result);   
            in.close();   
            http.disconnect();

https或http的get请求写好了,哦中间涉及到了一个getCookie的方法,如下:

/** 得到cookie */  
    private static void getCookie(HttpURLConnection http) {  
        String cookieVal = null;  
        String key = null;  
        DataDefine.mCookieStore = "";  
        for (int i = 1; (key = http.getHeaderFieldKey(i)) != null; i++) {  
            if (key.equalsIgnoreCase("set-cookie")) {  
                cookieVal = http.getHeaderField(i);  
                cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));  
                DataDefine.mCookieStore = DataDefine.mCookieStore + cookieVal  
                        + ";";  
            }  
        }  
    }


public static Query HttpQueryReturnClass(String httpUrl, String base64) {
	String result = "";   
        Log.i("控制", httpUrl);   
        Query obj = new Query();   
        HttpURLConnection http = null;   
        URL url;   
        try {   
            url = new URL(httpUrl);   
            // 判断是http请求还是https请求   
            if (url.getProtocol().toLowerCase().equals("https")) {   
                trustAllHosts();   
                http = (HttpsURLConnection) url.openConnection();   
                ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认   
            } else {   
                http = (HttpURLConnection) url.openConnection();   
            }   
            http.setConnectTimeout(10000);// 设置超时时间   
            http.setReadTimeout(50000);   
            http.setRequestMethod("POST");// 设置请求类型为post   
            http.setDoInput(true);   
            http.setDoOutput(true);   
            http.setRequestProperty("Content-Type", "text/xml");   
            http.setRequestProperty("Cookie", DataDefine.mCookieStore);   
            DataOutputStream out = new DataOutputStream(http.getOutputStream());   
            out.writeBytes(base64);   
            out.flush();   
            out.close();   
            obj.setHttpStatus(http.getResponseCode());// 设置http返回状态200还是403   
            BufferedReader in = null;   
            if (obj.getHttpStatus() == 200) {   
                getCookie(http);   
                in = new BufferedReader(new InputStreamReader(   
                        http.getInputStream()));   
            } else  
                in = new BufferedReader(new InputStreamReader(   
                        http.getErrorStream()));   
            result = in.readLine();// 得到返回结果   
            in.close();   
            http.disconnect();   
        } catch (Exception e) {   
            // TODO Auto-generated catch block   
            e.printStackTrace();   
        }   
}


 这里面的base64是我经过base64加密过以后的数据

转载地址:请点击

转载博客地址:请点击

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值