android - Self Signed Certificate - Trust anchor not found -
edit: bnk in comments has linked solution found here.
i'm sending off post requests via rest backend server (over lan), done on https. server has self signed certificate .pem file, works okay.
i'm trying connect different web server (over wan, through dns), self signed certificate .crt file (standard, ber/der format). now, although code same, receiving following exception:
java.security.cert.certpathvalidatorexception: trust anchor certification path not found.
i'm not sure why 1 server okay connect other not. not want trust certificates going on public internet.
my network code:
public httpsurlconnection setuphttpsconnection(string urlstring) { try { // load cas inputstream certificatefactory cf = certificatefactory.getinstance("x.509"); inputstream cainput = new bufferedinputstream(context.getassets().open("server.crt")); certificate ca = cf.generatecertificate(cainput); system.out.println("ca=" + ((java.security.cert.x509certificate) ca).getsubjectdn()); // 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); // create all-trusting host name verifier // avoid following : // java.security.cert.certificateexception: no name matching // because java default verifies certificate cn (common name) // same host name in url. if not, web service client fails. hostnameverifier allhostsvalid = new hostnameverifier() { @override public boolean verify(string arg0, sslsession arg1) { return true; } }; // install httpsurlconnection.setdefaulthostnameverifier(allhostsvalid); // tell urlconnection use socketfactory our sslcontext url url = new url(urlstring); httpsurlconnection urlconnection = null; urlconnection = (httpsurlconnection)url.openconnection(); urlconnection.setsslsocketfactory(sslcontext.getsocketfactory()); return urlconnection; } catch (exception ex) { log.e("networkmanager", "failed establish ssl connection server: " + ex.tostring()); return null; } } /** * represents asynchronous login/registration task used authenticate * user. */ public class posttask extends asynctask<postrequest, void, stringbuilder> { posttask() { } @override protected void onpreexecute() {} @override protected stringbuilder doinbackground(postrequest... params) { outputstream os = null; try { httpsurlconnection urlconnection = setuphttpsconnection(params[0].url); //sets maximum time wait input stream read complete before giving up. urlconnection.setreadtimeout(30000); //sets maximum time in milliseconds wait while connecting. urlconnection.setconnecttimeout(20000); urlconnection.setrequestmethod("post"); urlconnection.setdoinput(true); urlconnection.setdooutput(true); urlencodedformentity formentity = new urlencodedformentity(params[0].namevaluepairs); os = urlconnection.getoutputstream(); formentity.writeto(os); inputstream in = urlconnection.getinputstream(); stringbuilder ret = inputstreamtostring(in); return ret; } catch (ioexception e) { log.i("networkerror", e.tostring()); } catch (exception e) { } { if (os != null) { try { os.close(); } catch (ioexception ex) { } } } return null; } @override protected void onpostexecute(stringbuilder result) { } @override protected void oncancelled() { } }
if correctly understand idea "all trusting", hostname verifier in code, can refer following:
let's assume server app hosting inside iis has server certificate in "issued to"
"localhost"
, example. then, inside verify method can verify "localhost"
.
hostnameverifier hostnameverifier = new hostnameverifier() { @override public boolean verify(string hostname, sslsession session) { hostnameverifier hv = httpsurlconnection.getdefaulthostnameverifier(); return hv.verify("localhost", session); } };
Comments
Post a Comment