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) {
                            // TODO Auto-generated method stub
                            return true;
                    }
        }
        
        private class MyTrustManager implements X509TrustManager{

                    @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
                            
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                            // TODO Auto-generated method stub
                            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加密过以后的数据


转自:http://blog.csdn.net/a79412906/article/details/10060795







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值