Android平台上经常有使用https的需求,对于https服务器使用的根证书是受信任的证书的话,实现https是非常简单的,直接用httpclient库就行了,与使用http几乎没有区别。但是在大多数情况下,服务器所使用的根证书是自签名的,或者签名机构不在设备的信任证书列表中,这样使用httpclient进行https连接就会失败。解决这个问题的办法有两种,一是在发起https连接之前将服务器证书加到httpclient的信任证书列表中,这个相对来说比较复杂一些,很容易出错;另一种办法是让httpclient信任所有的服务器证书,这种办法相对来说简单很多,但安全性则差一些,但在某些场合下有一定的应用场景。这里要举例说明的就是后一种方法:实例化HttpClinet对象时要进行一些处理主要是绑定https连接所使用的端口号,这里绑定了443和8443:
- SchemeRegistryschemeRegistry=newSchemeRegistry();
- schemeRegistry.register(newScheme("https",
- newEasySSLSocketFactory(),443));
- schemeRegistry.register(newScheme("https",
- newEasySSLSocketFactory(),8443));
- ClientConnectionManagerconnManager=newThreadSafeClientConnManager(params,schemeRegistry);
- HttpClienthttpClient=newDefaultHttpClient(connManager,params);
上面的EasySSLSocketFactory类是我们自定义的,主要目的就是让httpclient接受所有的服务器证书,能够正常的进行https数据读取。相关代码如下:
- 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;
- }
- 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;
- }
- publicSocketcreateSocket()throwsIOException{
- returngetSSLContext().getSocketFactory().createSocket();
- }
- publicbooleanisSecure(Socketsocket)throwsIllegalArgumentException{
- returntrue;
- }
- publicSocketcreateSocket(Socketsocket,Stringhost,intport,
- booleanautoClose)throwsIOException,UnknownHostException{
- 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();
- }
- }
- publicclassEasyX509TrustManagerimplementsX509TrustManager{
- privateX509TrustManagerstandardTrustManager=null;
- 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];
- }
- publicvoidcheckClientTrusted(X509Certificate[]certificates,
- StringauthType)throwsCertificateException{
- standardTrustManager.checkClientTrusted(certificates,authType);
- }
- publicvoidcheckServerTrusted(X509Certificate[]certificates,
- StringauthType)throwsCertificateException{
- if((certificates!=null)&&(certificates.length==1)){
- certificates[0].checkValidity();
- }else{
- standardTrustManager.checkServerTrusted(certificates,authType);
- }
- }
- publicX509Certificate[]getAcceptedIssuers(){
- returnthis.standardTrustManager.getAcceptedIssuers();
- }
- }