天天看點

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{  

                public void checkclienttrusted(x509certificate[] chain, string authtype)  

                                throws certificateexception {  

                public void checkservertrusted(x509certificate[] chain, string authtype)  

                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[] {};

    }   

    public void checkclienttrusted(x509certificate[] chain, string authtype)

            throws certificateexception {

        // todo auto-generated method stub   

    public void checkservertrusted(x509certificate[] chain, string authtype)

        // system.out.println("cert: " + chain[0].tostring() + ", authtype: "   

        // + authtype);   

};  

 * 信任所有主機-對于任何證書都不做檢查  

 */  

class mytmarray implements x509trustmanager {  

    public x509certificate[] getacceptedissuers() {  

        // return null;  

        return new x509certificate[] {};  

    public void checkclienttrusted(x509certificate[] chain, string authtype)  

            throws certificateexception {  

        // todo auto-generated method stub  

    public void checkservertrusted(x509certificate[] chain, string authtype)  

        // 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;

    };  

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() {  

        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;   

            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  

                        http.geterrorstream()));   

            result = in.readline();   

            log.i("result", result);

            in.close();   

            http.disconnect();  

string result = "";  

        httpurlconnection http = null;  

        url url;  

            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()));  

                        http.geterrorstream()));  

            result = in.readline();  

            log.i("result", result);  

            in.close();  

 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   

                        + ";";

    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();

            http.setrequestmethod("post");// 設定請求類型為post   

            http.setdooutput(true);

            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;

            result = in.readline();// 得到傳回結果   

            http.disconnect();   

            // todo auto-generated catch block   

        string result = "";  

        log.i("控制", httpurl);  

        query obj = new query();  

            http.setrequestmethod("post");// 設定請求類型為post  

            http.setdooutput(true);  

            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;  

            result = in.readline();// 得到傳回結果  

            // todo auto-generated catch block  

 這裡面的base64是我經過base64加密過以後的資料

上一篇: squid

繼續閱讀