java - Trust Only Certificates Signed by Specific CA on Android 6 -


dear community of awesomeness,

i'm building secure app deals sensitive information. app communicates own restful api on ssl. don't want limit app specific certificate issued, rather trust certificates issued provider, e.g. comodo. way can extend , reissue certificate without having release app update.

i found great resource getting this done here android 6 deprecated httpclient , switched httpsurlconnection. google has their own approach posted here. on implementation, however, noticed instead of throwing "not trusted" exception different certificate, forced usage of local ca cert not behavior intended.

does have reference trusting specific ca using httpsurlconnection?

ok solved it, figured post solution in case else hits same problem. here code use json file using httpsurlconnection:

(...) public static class getjsontask extends asynctask<void, integer, asyncresponse> {      protected string jsondata;      protected igetjsonlistener listener;     protected context context = null;     protected string strurl;      public getjsontask(context c, igetjsonlistener l, string strurl) {         super();         listener = l;         context = c;         this.strurl = strurl;     }      @override     protected asyncresponse doinbackground(void... void) {          jsonobject jsonobjectresult = new jsonobject();         apistatus status;          if (isconnected(context)) {             httpsurlconnection httpsurlconnection=null;             try {                 //this key: context contains our ca cert                 sslcontext sslcontext = getsslcontext(context);                 if (sslcontext != null) {                     //for http basic auth if server implements                     //string encoded = base64.encodetostring(                     //        ("your_user_name" + ":" + "your_pwd").getbytes(),                     //        base64.default);                     url url = new url(strurl);                     httpsurlconnection = (httpsurlconnection) url.openconnection();                     httpsurlconnection.setrequestmethod("get");                     httpsurlconnection.setrequestproperty("content-length", "0");                     httpsurlconnection.setusecaches(false);                     httpsurlconnection.setallowuserinteraction(false);                     //for http basic auth                     //httpsurlconnection.setrequestproperty("authorization", "basic " + encoded);                     //this key: set connection use custom socket factory                     httpsurlconnection.setsslsocketfactory(sslcontext.getsocketfactory());                     //httpsurlconnection.setconnecttimeout(timeout);                     //httpsurlconnection.setreadtimeout(timeout);                     httpsurlconnection.connect();                     status = getstatusfromcode(httpsurlconnection.getresponsecode());                       listener.getjsonshowprogress(90);                      if (status == apistatus.ok) {                          bufferedreader bufferedreader = new bufferedreader(new inputstreamreader(httpsurlconnection.getinputstream()));                         stringbuilder stringbuilder = new stringbuilder();                          string line;                         while ((line = bufferedreader.readline()) != null) {                             stringbuilder.append(line);                         }                         bufferedreader.close();                         jsonparser parser = new jsonparser();                         string s = stringbuilder.tostring();                         jsonobjectresult = (jsonobject) parser.parse(s);                     }                 } else                     status = apistatus.auth_error;                 listener.getjsonshowprogress(99);             //this key: exception thrown if certificate             //is signed ca not our ca             } catch (sslhandshakeexception e) {                 status = apistatus.auth_error;                 //react man-in-the-middle attack             } catch (ioexception e) {                 status = apistatus.net_error;             } catch (jsonparseexception e) {                 status = apistatus.json_error;             } catch (exception e) {                 status = apistatus.unknown_error;             } {                 if (httpsurlconnection != null)                     httpsurlconnection.disconnect();             }         } else {             status = apistatus.net_error;         }         // if not successful issue call next hour.         asyncresponse response = new asyncresponse();         response.jsondata = jsonobjectresult;         response.opstatus = status;          return response;     }      @override     protected void onpreexecute() {         super.onpreexecute();         if (listener != null)             listener.getjsonstartprogress();     }      @override     protected void onprogressupdate(integer... progress) {         listener.getjsonshowprogress(progress[0]);     }      @override     protected void onpostexecute(asyncresponse result) {         listener.getjsonfinished(result.jsondata, result.opstatus);     }      public  interface igetjsonlistener {         void getjsonstartprogress();         void getjsonshowprogress(int percent);         void getjsonfinished(jsonobject resjson, apistatus status);     } } private static sslcontext getsslcontext(context context){     //mostly taken google code link in question.     try {         certificatefactory cf = certificatefactory.getinstance("x.509");          assetmanager = context.getassets();         //this key: ca's cert stored in /assets/         inputstream cainput = new bufferedinputstream(am.open("rootca.crt"));         certificate ca;         try {             ca = cf.generatecertificate(cainput);             //system.out.println("ca=" + ((x509certificate) ca).getsubjectdn());         } {             cainput.close();         }          // create keystore containing our trusted cas         string keystoretype = keystore.getdefaulttype();         keystore keystore = keystore.getinstance(keystoretype);         keystore.load(null, null);         keystore.setcertificateentry("ca", ca);          // create trustmanager trusts cas in our keystore         string tmfalgorithm = trustmanagerfactory.getdefaultalgorithm();         trustmanagerfactory tmf = trustmanagerfactory.getinstance(tmfalgorithm);         tmf.init(keystore);          // create sslcontext uses our trustmanager         sslcontext sslcontext = sslcontext.getinstance("tls");         sslcontext.init(null, tmf.gettrustmanagers(), null);         return sslcontext;     } catch (exception e){         return null;     }  }  public enum apistatus {     ok("ok.", 200), //all went     json_error("error parsing response.", 1),     net_error("network error.", 2), //we couldn't reach server     unknown_error("unknown error.", 3), //some sh*t went down      auth_error("authentication error.", 401), //credentials wrong     server_error("internal server error.", 500), //server code crashed     timeout("operation timed out.", 408); //network slow or server overloaded      private string stringvalue;     private int intvalue;      private apistatus(string tostring, int value) {         stringvalue = tostring;         intvalue = value;     }      @override     public string tostring() {         return stringvalue;     } }  private static apistatus getstatusfromcode(int code) {      if (code==200 || code==201) {         return apistatus.ok;     }else if (code == 401) {         return apistatus.auth_error;     } else if (code == 500) {         return apistatus.server_error;     } else if (code == 408) {         return apistatus.timeout;     } else {         return apistatus.unknown_error;     }  }  private static class asyncresponse {     public apistatus opstatus;     public jsonobject jsondata; } (...) 

usage straightforward:

public class myclass implements igetjsonlistener {      (...)      new getjsontask(context, this, "https://your.url.com/").execute();       @override      public void getjsonfinished(jsonobject resjson, apistatus status) {         //handle json content web here         (...)      }      (...) } 

i'd love hear improvements have.


Comments

Popular posts from this blog

matlab - error with cyclic autocorrelation function -

django - (fields.E300) Field defines a relation with model 'AbstractEmailUser' which is either not installed, or is abstract -

c# - What is a good .Net RefEdit control to use with ExcelDna? -