Android ignore https certificate verification
通过Https访问的时候经常会遇到"Not trusted Server Certificate"的问题,有人说在3.0上面没有这个问题,可能已经改进了,在2.2及以前的版本中有这个问题。 开始想的是采用安装证书的方法(Trusting SSL certificates),最后也没有成功,不知道是证书的原因还是其他,有人说安装证书只能在WIFI上使用,没有找到官方文档,用户可能在GPRS上使用,只能放弃。 StackOverflow上也有相关的方案,我整理了一下。 我将注册的步骤封装到DefaultHttpClient子类中了,这样看上去更清晰一些,你也可以 直接实例化DefaultHttpClient的方法。 SchemeRegistryschemeRegistry=newSchemeRegistry();schemeRegistry.register(newScheme("https",sslf,443)); SingleClientConnManagercm=new SingleClientConnManager(post.getParams(),schemeRegistry); HttpClientclient=newDefaultHttpClient(cm,post.getParams()); /** *@authorBrant *@decription */ publicclassSSLHttpClientextendsDefaultHttpClient{ @Override protectedClientConnectionManagercreateClientConnectionManager(){ SchemeRegistryregistry=newSchemeRegistry(); registry.register(newScheme("http",PlainSocketFactory .getSocketFactory(),80)); //443是Https的默认端口,如果网站配置的端口不一样,这里要记着改一下 registry.register(newScheme("https",newEasySSLSocketFactory(),443)); returnnewSingleClientConnManager(getParams(),registry); } publicstaticSSLHttpClientgetInstance(){ SSLHttpClientclient=newSSLHttpClient(); client.setCookieStore(mCookie); returnclient; } } EasySSLSocketFactory: importjava.io.IOException; importjava.net.InetAddress; importjava.net.InetSocketAddress; importjava.net.Socket; importjava.net.UnknownHostException; importjavax.net.ssl.SSLContext; importjavax.net.ssl.SSLSocket; importjavax.net.ssl.TrustManager; importorg.apache.http.conn.ConnectTimeoutException; importorg.apache.http.conn.scheme.LayeredSocketFactory; importorg.apache.http.conn.scheme.SocketFactory; importorg.apache.http.params.HttpConnectionParams; importorg.apache.http.params.HttpParams; /** *Thissocketfactorywillcreatesslsocketthatacceptsselfsigned *certificate * *@authorolamy *@version$Id:EasySSLSocketFactory.java7653552009-04-1520:59:07Zevenisse *$ *@since1.2.3 */ publicclassEasySSLSocketFactoryimplementsSocketFactory, LayeredSocketFactory{ privateSSLContextsslcontext=null; privatestaticSSLContextcreateEasySSLContext()throwsIOException{ try{ SSLContextcontext=SSLContext.getInstance("TLS"); context.init(null,newTrustManager[]{newEasyX509TrustManager( null)},null); returncontext; }catch(Exceptione){ thrownewIOException(e.getMessage()); } } privateSSLContextgetSSLContext()throwsIOException{ if(this.sslcontext==null){ this.sslcontext=createEasySSLContext(); } returnthis.sslcontext; } /** *@seeorg.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket, *java.lang.String,int,java.net.InetAddress,int, *org.apache.http.params.HttpParams) */ publicSocketconnectSocket(Socketsock,Stringhost,intport, InetAddresslocalAddress,intlocalPort,HttpParamsparams) throwsIOException,UnknownHostException,ConnectTimeoutException{ intconnTimeout=HttpConnectionParams.getConnectionTimeout(params); intsoTimeout=HttpConnectionParams.getSoTimeout(params); InetSocketAddressremoteAddress=newInetSocketAddress(host,port); SSLSocketsslsock=(SSLSocket)((sock!=null)?sock:createSocket()); if((localAddress!=null)||(localPort>0)){ //weneedtobindexplicitly if(localPort<0){ localPort=0;//indicates"any" } InetSocketAddressisa=newInetSocketAddress(localAddress, localPort); sslsock.bind(isa); } sslsock.connect(remoteAddress,connTimeout); sslsock.setSoTimeout(soTimeout); returnsslsock; } /** *@seeorg.apache.http.conn.scheme.SocketFactory#createSocket() */ publicSocketcreateSocket()throwsIOException{ returngetSSLContext().getSocketFactory().createSocket(); } /** *@seeorg.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket) */ publicbooleanisSecure(Socketsocket)throwsIllegalArgumentException{ returntrue;//不判断socket,直接返回true } /** *@seeorg.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, *java.lang.String,int,boolean) */ publicSocketcreateSocket(Socketsocket,Stringhost,intport, booleanautoClose)throwsIOException,UnknownHostException{ //return getSSLContext().getSocketFactory().createSocket(); //will get java.io.IOException: SSL handshake failure: I/O error //during system call, Broken pipe returngetSSLContext().getSocketFactory().createSocket(socket,host, port,autoClose); } //------------------------------------------------------------------- //javadocinorg.apache.http.conn.scheme.SocketFactorysays: //BothObject.equals()andObject.hashCode()mustbeoverridden //forthecorrectoperationofsomeconnectionmanagers //------------------------------------------------------------------- publicbooleanequals(Objectobj){ return((obj!=null)&&obj.getClass().equals( EasySSLSocketFactory.class)); } publicinthashCode(){ returnEasySSLSocketFactory.class.hashCode(); } } EasyX509TrustManager: importjava.security.KeyStore; importjava.security.KeyStoreException; importjava.security.NoSuchAlgorithmException; importjava.security.cert.CertificateException; importjava.security.cert.X509Certificate; importjavax.net.ssl.TrustManager; importjavax.net.ssl.TrustManagerFactory; importjavax.net.ssl.X509TrustManager; /** *@authorolamy *@version$Id:EasyX509TrustManager.java7653552009-04-1520:59:07Zevenisse *$ *@since1.2.3 */ publicclassEasyX509TrustManagerimplementsX509TrustManager{ privateX509TrustManagerstandardTrustManager=null; /** *ConstructorforEasyX509TrustManager. */ publicEasyX509TrustManager(KeyStorekeystore) throwsNoSuchAlgorithmException,KeyStoreException{ super(); TrustManagerFactoryfactory=TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); factory.init(keystore); TrustManager[]trustmanagers=factory.getTrustManagers(); if(trustmanagers.length==0){ thrownewNoSuchAlgorithmException("notrustmanagerfound"); } this.standardTrustManager=(X509TrustManager)trustmanagers[0]; } /** *@seejavax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[], *StringauthType) */ publicvoidcheckClientTrusted(X509Certificate[]certificates, StringauthType)throwsCertificateException{ standardTrustManager.checkClientTrusted(certificates,authType); } /** *@seejavax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], *StringauthType) */ publicvoidcheckServerTrusted(X509Certificate[]certificates, StringauthType)throwsCertificateException{ if((certificates!=null)&&(certificates.length==1)){ certificates[0].checkValidity(); }else{ standardTrustManager.checkServerTrusted(certificates,authType); } } /** *@seejavax.net.ssl.X509TrustManager#getAcceptedIssuers() */ publicX509Certificate[]getAcceptedIssuers(){ returnthis.standardTrustManager.getAcceptedIssuers(); } } 然后直接实例化SSLHttpClient就可以想Http一样执行HttpGet和HttpPost方法了,希望能有所帮助:)。 本文转自 breezy_yuan 51CTO博客,原文链接:http://blog.51cto.com/lbrant/795636,如需转载请自行联系原作者