您的位置:首页 > 移动开发 > Android开发

[整理]Android移动开发之数据传输安全

2015-03-16 19:42 330 查看

Android移动开发之数据传输安全

整理自
Fish_Ou

0x0 概述

移动应用很多时候并非孤立存在,在多数场景下存在前、后台以及第三方服务之间进行数据交互,因此,在网络中传输敏感数据在所难免,如果不使用正确安全的传输方式,有可能存在敏感信息泄漏的风险。

0x1安全准则

A.使用SSL协议(或基于SSL的协议)传输敏感数据。

B.验证服务器证书的有效性,防止中间人攻击,当证书有效性验证失败时应强行断开连接,而不是提示用户。

C.尽可能地减少使用短信发送敏感信息。

D.增强项:应用程序可以对敏感数据进行一次独立加密后再通过SSL进行传输。

0x2详细描述

可以使用“证书锁定”(certificate pinning)的方式验证证书的有效性,即在代码中精确的验证当前服务器是否持有某张指定的证书。X509TrustManager接口是实现证书锁定一种方法,它通过在SSL回调函数中读取服务器证书密钥并和程序预埋的证书密钥进行对比,如果两者不一致则强行断开链接。

任何申请了READ_SMS permission的应用都可以读取短信内容,故应尽量减少使用短信发送敏感信息。
应用自身进行一次独立加密的好处是,当出现SSL协议相关漏洞(比如影响巨大的openssl heart bleed漏洞)时能够有效减少损失。
“证书锁定”的缺点是:由于证书是预埋在应用程序内的,是当服务器更新证书时,应用程序也要同步更新。

0x3 Android证书有效性验证方案

1.SSL劫持攻击

目前虽然很多Android APP使用了https通信方式,但是只是简单的调用而已,并未对SSL证书有效性做验证。在攻击者看来,这种漏洞让https形同虚设,可以轻易获取手机用户的明文通信信息,攻击示意图如下:



2.解决方案

(1) 服务器证书锁定

简介:服务器证书锁定的原理是在代码中精确的验证当前服务器是否持有某张指定的证书。X509TrustManager接口是实现证书锁定一种方法,它通过在SSL回调函数中读取服务器证书密钥并和程序预埋的证书密钥进行对比,如果两者不一致则强行断开链接。

流程图:



代码参考:

/* 使用https需要定义实现X509TrustManager接口的类,并重写里面的方法,这些方法会在建立SSL链接的过程中被自动调用 */

public final class PubKeyManager implements X509TrustManager

{

         /* 此处存放服务器证书密钥 */

  private static String PUB_KEY =

                       "30820122300d06092a864886f70d01010105000382010f"

                            + "003082010a0282010100973a0569971991dc9446f309ec0af7646377dca80eb1"

                            + "e1357f5fb5c69d046d03d23f6cf743d155e7b44d834cf71d6500a8b1e38110b5"

                            + "35ad07212a50e1f3ab497acfde74e065018d64136d14d63d04604124aacd74ea"

                            + "037a5f8d6894aadd58f7774655761c9fba22426935794f6740fa89b6f7e902b8"

                            + "e02c0b842116272701c9edaef62c977b0df488847c2e0a75028865be34c98903"

                            + "be11a2cf4495acec5c958ddf64619808e641bac64ab432e4638e969f4214d7bc"

                            + "88db81feaef4d5d329f93f2e79535b2d00c01145823b664ca7ab8db9de858d29"

                            + "161c6cce86decb6a4f66cf86afb79e182a5b5a2bb6d8795af749f7af356aef2e"

                            + "64b6ae785ff88d456f970203010001";

 

         /*  https协商中获取的服务器证书链(chain)将自动传入该方法 */

  public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException

  {

    if (chain == null) {

      throw new IllegalArgumentException("checkServerTrusted: X509Certificate array is null");

    }

 

    if (!(chain.length > 0)) {

      throw new IllegalArgumentException("checkServerTrusted: X509Certificate is empty");

}

 

         /* authType为建立SSL链接时使用的非对称加密算法,RSA为业界主流算法 */

    if (!(null != authType && authType.equalsIgnoreCase("RSA"))) {

      throw new CertificateException("checkServerTrusted: AuthType is not RSA");

    }

 

    /* 执行SSL/TLS常规性检查 */

    try {

      TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");

      tmf.init((KeyStore) null);

     

      for (TrustManager trustManager : tmf.getTrustManagers()) {

        ((X509TrustManager) trustManager).checkServerTrusted(chain, authType);

      }

    } catch (Exception e) {

      throw new CertificateException(e);

}

 

/* 将编码后的密钥转换成16进制形式的大整数 */

    RSAPublicKey pubkey = (RSAPublicKey) chain[0].getPublicKey();

    String encoded = new BigInteger(1, pubkey.getEncoded()).toString(16);

 

    /* 比较预埋证书密钥和服务器证书密钥是否一致 */

    final boolean expected = PUB_KEY.equalsIgnoreCase(encoded);

    if (!expected) {

      throw new CertificateException("checkServerTrusted: Expected public key: "

                + PUB_KEY + ", got public key:" + encoded);

      }

    }

  }

}

(2) 根证书锁定+域名验证

简介:和服务器证书锁定类似,区别在于该方案检查服务器证书是否由指定的CA证书签名,即检查签名服务器证书的CA证书的公钥和本地预置的CA证书公钥是否一致,同时,还会进一步校验服务器证书的域名是否有效。

流程图:



(3)方案对比

方案
优点
缺点
服务器证书锁定
安全性最高,实施攻击必须拿到对应服务器私钥证书。
更换证书时APP影响大
根证书锁定+域名验证
更换服务器证书不受影响
安全性和CA机构以及域名验证机制有关。

有关下载

链接: http://pan.baidu.com/s/1mgtDIXi 密码: jb8a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: