Android中使用https(HTTP+SSL)访问服务器

之前做网络请求一直都是用Http请求来和服务器交互,一直听说过Https不过一直没用过,所以今天决定好好研究一下,一把鼻涕一把泪啊,结果发现……….哎,不说了,说多了都是泪;这里记录一下android怎么使用https和服务器互交。

HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。


  • 首先第一步(生成证书)

    1.0,生成服务端的证书:
    打开cmd命令行窗口,运行:(test是证书名字)
    keytool -genkey -alias test -keystore test.jks(test.jks这个需要保存下来在配置tomcat服务器中需要使用)

    1.1,把证书中的密钥导出:
    keytool -exportcert -alias test -file test.cert -keystore test.jks

    1.2,生成android端的证书:
    在坑爹的Android 要求要BC证书,而Java的keytool本身不提供BKS格式,因此要自己手动配置。
    配置:
    1.2.1:先到http://www.bouncycastle.org/latest_releases.html这里去下载一个工具包bcprov-ext-jdk15on-151.jar(这个工具包有相对应的jdk版本)
    1.2.2:把这个jar包复制到
    C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\
    1.2.3:配置bcprov(jdk\jre\lib\security\目录中找到 java.security 在内容增加一行security.provider.11 =org.bouncycastle.jce.provider.BouncyCastleProvider )
    1.2.4:使用命令生成证书 keytool
    -importcert -keystore test.bks -file test.cert-storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider

    注意:以上操作如果没有设置路径,则所有生成好的文件都在C:\用户\下面可以找到。


上面已经把需要的证书以及准备好,那么就可以开始android端的代码书写了

  • Android端
  private static DefaultHttpClient getDefaultHttpClient(){
        if(client==null){
            HttpParams params=new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, "UTF-8");
            HttpProtocolParams.setUserAgent(params, AGENT_INFO);
            ConnManagerParams.setTimeout(params, 5000);
            SchemeRegistry registry=new SchemeRegistry();
            //让请求支持http  和https两种模式
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory( ), 80));
            //系统标准的SSLSocketFactory.getSocketFactory()
            //添加证书
            registry.register(new Scheme("https",SSLTrust.getSocketFactory1(mcontext), 443));
            ThreadSafeClientConnManager conMgr = new ThreadSafeClientConnManager(params, registry);
            client = new DefaultHttpClient(conMgr,params);
        }
        return client;
    }

    上面的SSLTrust就是我们自己定义的一个SSLSocketFactory,SSLTrust继承于SSLSocketFactory:
    public SSLTrust(KeyStore truststore)
         throws NoSuchAlgorithmException,
            KeyManagementException,
                 KeyStoreException,
                    UnrecoverableKeyException {
         super(truststore);
        // TODO Auto-generated constructor stub
        s_context=SSLContext.getInstance("TLS");
        s_context.init(null, 
        new TrustManager[]{new SSLTrustAllManager()}, null);
        //设置主机过滤,允许所有的
        setHostnameVerifier(
             SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    }

    重写createSocket方法
    @Override
    public Socket createSocket(Socket socket,
             String host, int port,boolean autoClose) 
                     throws IOException,
                          UnknownHostException {
        // TODO Auto-generated method stub
        return s_context.getSocketFactory()
        .createSocket(socket, host, port, autoClose);
    }

    然后在提供一个对外的方法:
    public static SSLSocketFactory getSocketFactory1(
    Context context){
        try {
            KeyStore keystore=KeyStore
                .getInstance(KeyStore.getDefaultType());
            InputStream keyStroreInputStream
                 =context.getAssets().open("test.bks");
            //公钥
            keystore.load(keyStroreInputStream,
                  pass.toCharArray());
            SSLTrust trust=new SSLTrust(keystore);
            return trust;
        } catch (KeyStoreException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (KeyManagementException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (CertificateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

以上就是Android客户端,已经配置完毕。

  • 服务器端配置https的ssl证书
    这里以Tomcat为例。
    找到Tomcat的配置文件(E:\Tomcat\Tomcat 6.0\conf\server.xml);
    然后打开文件,把已经注释的这段代码给恢复,也就是去掉注释
    去掉注释以后,在加上我们的密钥truststoreFile,keystoreFile:
  <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               truststoreFile="E:\\secry\\test.jks" 
               truststorePass="123456"
               keystoreFile="E:\\secry\\test.jks" 
               keystorePass="123456"/>

这里配置完成后基本上就可以走通了,当你用https://192.168.1.124:8443/httpsservices/Mode1!login去访问的时候描绘提示说证书不安全:这里写图片描述

好了 到这里就基本完成了,这证书者玩意是要钱的要money的,我们自己生成测试的没什么用,其实12306也是用的自己的证书,当你用ie去访问12306的时候,浏览器会提示你12306是一个危险的网站,不推荐继续访问,当然你可以点击继续访问。
最后附上测试demo:http://download.csdn.net/detail/leifengpeng/8704155

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值