专栏名称: AndoirdBlogCN
[ Android Blog 周刊 ]每周一准时更新,主要包括本周最新的优秀国内外博客,新闻,类库,视频等 [www.androidblog.cn ] [ QQ群:149581646 ]
目录
相关文章推荐
复利大王  ·  某国资PE:月入6k你玩什么命啊! ·  20 小时前  
复利大王  ·  O站要卖身了 ·  20 小时前  
复利大王  ·  满级英语翻译,看完笑的肚子疼!哈哈 ·  20 小时前  
复利大王  ·  现在已经没有体面的工作了 ·  2 天前  
复利大王  ·  协和终于开始自查了 ·  2 天前  
51好读  ›  专栏  ›  AndoirdBlogCN

Android 密钥保护和 C/S 网络传输安全理论指南

AndoirdBlogCN  · 公众号  · android  · 2016-12-24 08:23

正文

请到「今天看啥」查看全文


这就是使用 KeyStore 的一整套流程,另外 KeyStore 还可以用来做数据签名和签名验证,就像一个黑匣子一样,具体可以自行搜索了解。

KeyStore 适用于生成和存储密钥,这些密钥可以用来加密运行时获取到的数据,比如运行时,用户输入的密码,或者服务端传下来的 token。但对于需要预设在 App 内的 API key / secret,因为 KeyStore 是运行时随机生成加密密钥,所以我们无法预估API key / secret 会被加密成什么样,自然也就无法预先把加密后的 API key / secret 预埋在 App 内,因此对于这类需要预设的固定密钥,我将介绍另外一种十分安全、难破解的保护方式。

首先我们需要思考,这个 key 应该放到哪里才能够最大限度提升其被逆向获取的难度,放 Java 代码里?根本不安全。放文件或图片像素里?顶多续 1 小时。放 so 库里?可以,so 库能够很大程度提升逆向破解难度,但如果别人把 so 库文件拿出来,再直接调用这些 native 接口,便也可以获取到你的 key,怎么办?

我的做法是在 so 库的 C 代码里 JNI_OnLoad() 方法对 APK 签名进行验证,如果签名不对,直接 crash,这样移植出去便和砖头没什么两样。而你的应用又不得不依赖这个 so 库进行获取 API key / secret,因此它又不能直接剥离,这就保证了不能没有它,又不能移植它,换句话说就是:如果别人反编译了你的代码,发现你使用 so 进行签名验证,便直接把这个 so 文件摘掉,这样做的结果是,App 获取不到你存在 so 中的 secret 了,便无法正常工作了;而如果别人对你的应用进行修改和重新签名,或移植你的 so 库来读取内部的 secret,则会因为签名验证不通过直接自爆。

以上便是对于保护 key / secret 的一些有效举措,再总结下就是,使用 so 库存储预设 key / secret,使用 Android KeyStore 存储运行时动态获取到的私密内容。

而另一方面,对网络传输进行加密、防中间人攻击也是至关重要的,如果你的密钥保护得很好,但数据却在网络传输过程中被拦截篡改,那也是前功尽弃。

如果使用 HTTP,对于 API 请求参数会变的请求,一般都会进行参数防篡改校验,和参数加密,客户端和服务端会约定一个固定的密钥作为加密的 key,这个 key 便属于上面我们讲过的需要预设在 App 代码里的,因此比较安全的做法就是将它埋藏在 so 库里。

但更推荐、更简单的做法是,使用 HTTPS,HTTPS 是 HTTP 的安全版本,为什么这么说呢?因为HTTPS 自带加密、验签、检查数据完整性等功能,它在 HTTP 下加入了 SSL (Secure Socket Layer),SSL 位于 TCP/IP 和 HTTP 协议之间,负责加密、验签、检查数据完整性工作。

HTTPS 的握手过程中能够确立客户端与服务端双方加密传输数据的密码信息,流程大致如下:

  1. 客户端将自己支持的加密算法类型和检验数据完整性的 HASH 算法类型告诉服务端

  2. 服务端从客户端传上来的加密算法中选出一种支持的类型,用于生成一对非对称密钥对,并将自己的证书发给客户端,证书中将带有这对非对称密钥的公钥和证书颁发机构、过期时间等。其中所谓的非对称加密及其公钥和密钥,如果不懂,可以简单理解为:这是一种加密算法,私钥加密的内容只有公钥才能解密,反之公钥加密的内容只有私钥才能解密,以此来保证两端信息的安全性。

  3. 客户端获得证书后,会对证书的合法性进行检验,如果证书合法,则客户端将随机生成一对称加密的密钥,并使用服务端给的非对称加密密钥对这个对称加密密钥进行加密,并生成 HASH 值,统一发给服务端。所谓对称加密及其密钥,简单说:这是一种加密算法,加密和解密使用的密钥是一样的。

  4. 服务端拿到信息后,使用私钥进行解密取出对称加密的密钥,并验证 HASH 值。验证无误后,使用这个对称加密密钥对握手信息进行加密,发给客户端。

  5. 客户端解密和 HASH 验证,无误则握手成功完成。接下来所有的通讯都会使用这个已经同步到两端的对称加密密钥进行加密通讯。而一旦这个握手过程中有任何错误,都会中止握手过程,请求的参数和内容传输是在这些过程之后,因此若是握手过程出错,则不会发送请求内容。

但是,尽管有了以上机制来保证端与端之间通信的安全,仍然无法保证安全,因为防不住中间人攻击,也就是说,如果有个中间人横跨在你的客户端与服务端之间,你以为你在和服务端握手,但实际上是在与这个中间人握手,这个中间人将持有你目标服务端的公钥,以及它自己产生的密钥和公钥,然后把它自己产生的公钥交给你,你以为你拿到手的是服务端直接给你的公钥,因此这个中间人能够解密你的所有请求。

你的客户端







请到「今天看啥」查看全文


推荐文章
复利大王  ·  某国资PE:月入6k你玩什么命啊!
20 小时前
复利大王  ·  O站要卖身了
20 小时前
复利大王  ·  满级英语翻译,看完笑的肚子疼!哈哈
20 小时前
复利大王  ·  现在已经没有体面的工作了
2 天前
复利大王  ·  协和终于开始自查了
2 天前
朱莉生活日记  ·  手把手教会你有关馄饨的一切!
8 年前