API接口规范

API接口安全设计规范

App的数据来源就是API接口,所以API接口对APP的重要性不言而语。设计API接口需要考虑的就是安全机制。

  • 防篡改
    防篡改就是防止请求的URL参数值发送至服务器的时候被改动。
    普通的API接口格式是xxx.html&key1=xx?key2=xx。我们采用sign签名的发送保证数据传输的正确性。
    App一般会在公司的后台申请一个appKey和appSecret,这两个是一一对应的。appKey会作为一个参数写在URL中,然后再发送至服务器。appSecret则用于参与生成sign的计算。一般采用安全散列算法实现,如SHA1.
    sign也要作为一个参数添加到URL中,和appKey一并发送至服务器,如xxx.html&key1=xx?key2=xx?appKey=xx?sign=xx。服务器接收到请求后,会通过appKey查找对应的appSecret,然后通过同样的散列算法,得到一个sign,最后对比一下两个sign是否相等。如果不相等则数据遭到篡改,废弃这条请求。
    (app发起http请求,对参数排序,然后使用参数与私钥拼接,在进行sha1加密等方式,生成一个签名出来,一起发给服务端,服务端这边获取到参数,签名,再使用自己的私钥进行同样方式的加密生成签名,比对签名是否一致。一致则认为合法,不一致则不合法。但是无法防止重复请求攻击)
    另外,关于appSecret有以下两种使用方式:1.appSecret直接写在客户端代码中,这样即可直接获取调用。2.appSecret还可以通过一个专门的getSign从后台获取。这种情况首先需要用户登录,登录成功后,服务器返回一个accessToken参数,然后调用appSecret接口时需要带上这个参数。

  • 防重放
    解决了数据被篡改的问题之后,还有一个问题就是,如果一条正常的请求数据被其他人获取到了,从而进行多次请求该怎么办?
    可以采用nonce+timestamp的解决方案。
    1.nonce
    nonce是一个随机数,有客户端生成,每次请求时将随机数作为一个参数发送给服务端。服务端会在数据库里查询是否有这个nonce,如果没有则时一条新的请求,进行正常处理即可;如果能查到已经存在这个nonce,则废弃这条请求。
    nonce可以通过UUID.randomUUID().toString()来生成。
    有个问题是,这个nonce在数据库中随着请求量的增大,产生的数据量也会越来越大。为了解决这个问题,我们可以采用timestamp时间戳的方式。
    2.timestamp
    时间戳是服务器给URL请求设定的一个有限时间范围起点。例如服务器认为客户端发送过来的timestamp与服务器当前的时间戳之差在10分钟值内,则认为这条请求是有效的。超过了10分钟则废弃这条请求。如果是10分钟内的请求,需要在数据库中查询nonce是否有记录,如果有记录,则废弃这条请求;如果没有记录,则记录这个nonce,并且将超过10分钟的nonce全部删除。
    关于这个timestamp获取的问题,同样需要从服务器获取,不然客户端怎么知道服务器的起点计算时间呢?上面说到有个获取appSecret的接口,其实我们可以在这个接口中一并获取timestamp。
    需要注意的是,客户端需要在每次发送URL请求的时候,计算一下timestamp的值。例如获取到的timestamp=1564588800,那么下次请求的timestamp的值是1564588800+diffTime。服务器收到timestamp会跟服务器当前的时间戳做对比,看是否大于10分钟。
    因此,一条正常的URL格式请求如下:
    demo.html?nonce=xx&timestamp=xx&appKey=xx&sign=xx&key1=xx&key2=xx

  • HTTPS
    HTTPS是用SSL+HTTP构建的可用于网络传输以及身份认证的网络协议。HTTP使用明文通信,传输的内容可以通过抓包工具截取,HTTPS自动对数据进行加密压缩,防止监听,防止被抓包以看到明文,防止中间人截取。
    苹果从iOS9就开始默认使用HTTPS,Android9.0也开始强制使用HTTPS了,默认阻塞HTTP请求。

API接口通用设计规范

1.版本号
每一组API接口需要对应一个大版本号,大版本号一般是跟App的大版本对应的。例如App第一版本命名为v1,App第二版本经过改版后,接口返回的内容一般也会变化,这里命名为v2。

示例如下:
/api/v1/userinfo:表示v1这个大版本的App,有一个userinfo业务类型的接口。
/api/v2/userinfo:表示v2这个大版本的App,有一个userinfo业务类型的接口。
/api/v2.1/userinfo:表示v2这个大版本中,对userinfo业务接口进行了一些细微调整。

2.请求参数
请求参数由公共请求参数和业务请求参数组合而成。
1)公共请求参数

参数名 参数类型 是否必填 描述
nonce String 防重放攻击
timestamp String 防重放攻击
sign String 请求参数的签名
accessToken String 鉴权标志,用于登陆判断
appKey String 防篡改
version String 客户端版本号

其中version表示客户端版本号,此处将其传给服务器,由服务器根据客户端版本号进行一定的业务逻辑判断。
2)业务请求参数
以登录为例

参数名 参数类型 是否必填 描述
name String 姓名
password String 密码

一个完整的URL如下:
/api/v1/getUserInfo.do?nonce=xx&timestamp=xx&appKey=xx&appKey=xx&name=xx&password=xx

3.返回值
使用JSON格式返回API请求的结果。JSON格式简洁,传输数据量小,而且能展示复杂的数据结构。

{"body":{}"code":0"msg":""
}
  • code:API接口执行状态,例如0表示成功,-100表示为例超时。
  • msg:非成功状态下需要说明的信息,一般与code状态码一一对应定义。
  • body:返回的具体数据,通常是JSON格式。

4.接口变更
一般来说,一个API接口投入使用后,除非这个接口确定废弃不再使用,不然一般情况下不能对这个接口进行修改。例如修改了API的请求参数和返回值,会对使用此API接口的App带来不可预估的影响,最严重的影响就是崩溃。

5.Restful API
Restful API:/api/v1/userinfo
Restful API通过URI(如api/v1/userinfo)来表示资源,通过GET、POST、PUT、DELETE等方法来表示操作行为。

  • GET:获取资源。
  • POST:新建资源。
  • PUT:更新资源。
  • DELETE:删除资源。

SDK设计规范

SDK通用规范

  • SDK发布时需要配套有完整且详细的使用说明文档,包括混淆配置说明。
  • SDK需要详细记录每个版本的变更内容。
  • SDK如果对外开放,需要有一个专门的网站,同时附上SDK的说明文档,demo,变更历史等。
  • SDK的minSdkVersion要尽量小。
  • 尽量不要引用第三方库,要尽量使用Android系统自带的功能,然后在其基础上进行封装。如果一定要用到第三方库,可以使用provided依赖,并告知调用方主动依赖这个第三方库。
  • SDK内部对于关键路径要有详细的Log记录,便于后期排查问题。
  • SDK对外提供的接口,需要对其传入的参数和合法性和有效性进行检测。
  • SDK需要有较强的容错性,要增大力度对SDK内部的异常进行捕获。
  • 如果打出来的包是AAR格式的,需要注意res下面的资源文件名称,以避免和调用方的res文件名称冲突,所以一般SDK里面的res文件名称需要加入特定的修饰符,例如公司+项目名称。

SDK开发规范

SDK需要做到代码结构层次分明,功能清晰。
一个典型的SDK一般可以分为以下3层。
1.接入层
接入层的功能就是对外提供接口,供给调用方使用。一般对外提供的接口我们会定义一个接口文件,里面的方法都是可以对外提供的接口。所以接入层一般都是定义的接口文件,另外还有一个统一管理所有业务功能模块的雷,是外界跟sdk交互的统一入口。它还负责统一配置和进行初始化工作,例如初始化业务模块的Manager文件。

2.业务层
业务层的作用就是实现具体的业务逻辑。对于业务层的设计,我们会按照业务功能划分为不同的模块,每一个模块通过对应的Manager文件进行管理,并且Manager文件会具体实现接入层定义的接口方法。
3.基础层
基础层里面包括各种功能模块,例如SDK自行封装的网络请求模块,还有数据库模块、日志模块、Crash模块等。总而言之就是对业务层的支持。

App常用安全开发规范

组件外露

Android的四大组件Activity、Service、ContentProvider、BroadcastReceiver,有一个android:exported属性。如果是false,那么只能在同一个应用程序组件间或带有相同用户id的应用程序间才能启动或绑定该服务;如果是true,则该组件可以被任意应用启动或执行,这样就会有组件被恶意调用的风险。
如果组件没有包含过滤器intent-filter,那么android:exported属性的值默认是false;如果组件中包含了至少一个intent-filter,那么android:exported属性的值默认是true。
如果必须暴露这些组件,那么需要添加自定义的permission权限来进行访问控制。

<activity android:exported="true"android:name=".DemoActivity"android:permission="com.androidwind.permission.demoPermission"
/>

外部应用如果想直接打开DemoActivity,需要在AndroidManifest中进行配置:

<uses-permission android:permission="com.androidwind.permission.demoPermission"/>

WebView

因为webview在低系统版本中存在远程代码执行漏洞,如JavaScriptInterface,中间人可以利用此漏洞执行任意代码,所以app的targetSdkVersion需要大于17,另外需要将webview自动保存密码的功能关闭:

webview.getSettings().setSavePassword(false)

so文件

通常简单的做法是将密钥等敏感信息保存在java代码中,例如直接写在静态变量里,但是这样很容易被编译破解,即使代码有混淆。
可以考虑将一些敏感信息,通过cpp代码保存在so文件中。这样会增加敏感信息被破解的难度。
需要说明的是,如果使用so文件,那么这个so文件也需要加壳。
github上有一个可以自动生成加密so库的插件cipher.so,这样通过在gradle里面配置需要加密的数据,即可加密保存到so库,并且自动生成对应的java接口。

Android开发规范相关推荐

  1. android 开发规范1

    Android开发规范 一.Android编码规范 1.java代码中不出现中文,最多注释中可以出现中文 2.局部变量命名.静态成员变量命名 只能包含字母,单词首字母出第一个外,都为大写,其他字母都为 ...

  2. Android接口一般定义格式,Android开发规范

    原标题:Android开发规范 一.书写规范 1. 编码方式统一用UTF-8. 2. 花括号不要单独一行,和它前面的代码同一行.而且,花括号与前面的代码之间用一个空格隔开. 3. 空格的使用 if.e ...

  3. 三天,我通过了Apsara Clouder基础技能认证:阿里巴巴Android开发规范

    花费了三天时间学习了阿里巴巴 Android 开发规范,顺便通过了Apsara Clouder基础技能认证:阿里巴巴Android开发规范.证可能用处不大,但能反向push自己:1.注重代码规范,磨练 ...

  4. Android开发规范[Java+android]

    说明:该文档由阿里<Java开发规范>和<Android开发规范>整理而来  [强制]必须遵守,违反本约定或将会引起严重的后果:  [推荐]尽量遵守,长期遵守有助于系统稳定 ...

  5. Android开发规范:API接口安全设计规范

    公众号[国民程序员]回馈粉丝福利: 现金红包和送书活动火热进行中,点击参与! 我的新书<Android App开发入门与实战>已于2020年8月由人民邮电出版社出版,欢迎购买. 书籍详情请 ...

  6. Android 开发规范(完结版)

    点击上方蓝字关注公众号 码个蛋第270次推文 长文干货 作者:Blankj 博客:https://www.jianshu.com/u/46702d5c6978 文章目录 前言 AS 规范 命名规范 代 ...

  7. 阿里Android开发规范:安全与其他

    以下内容摘自 阿里巴巴Android开发手册 我们的目标是: 防患未然,提升质量意识,降低故障率和维护成本: 标准统一,提升协作效率: 追求卓越的工匠精神,打磨精品代码. [强制]必须遵守,违反本约定 ...

  8. android 开发规范

    前言 在开发中,一个良好的开发习惯以及一个开发规范可能会让你少走很多弯路,也会一定程度上的提高代码的可读性,可维护性和可拓展性.当随着需求的不断变更,需要维护项目的时候.当随着项目的代码量的提升,需要 ...

  9. Android开发规范,flutter生成二维码

    变量命名要做到足够长有一定意义,同时又足够短以避免冗长. 关于携带Android控件的变量,个人建议规则:[控件逻辑名称]+[控件缩写] 如mLoginBtn, mBottomLayout, mTit ...

最新文章

  1. 移动相关HTML设置
  2. [GDAL]写入shp
  3. chromium浏览器_微软将全面向Windows 10用户推送Chromium版Edge浏览器
  4. 基于Ogre的DeferredShading(延迟渲染)的实现以及应用
  5. Python将txt文件转为json文件
  6. mysql怎么进行删除操作_利用PHP怎么对MySQL数据库进行删除操作
  7. c语言电子时钟设计报告,电子时钟设计实验报告.doc
  8. 笔记本光驱位固态硬盘重装系统
  9. WdatePicker 诱发 “无法打开站点,已终止操作”错误
  10. 关于周期性学习率(Cyclical Learning Rate, CLR)
  11. Java旅游管理系统的设计与实现毕业设计
  12. 红茶保质期一年半,我都放了五年了,打开还有茶味,能喝吗?
  13. SQL SERVER 服务器登录名、数据库用户名、服务器角色、数据库角色、DENY、sp_addlogin ETC.
  14. 【墙裂推荐】二维码生成器哪个好?
  15. Mybatis遇到的报错集合
  16. 中文分词-转载3_一个北京程序员
  17. oracle consistent gets,consistent gets在Oracle使用特例
  18. 华天软件 SINOVATION 9.1 自主可控三维CAD内核CRUX IV 历史由来
  19. 联想拯救者r7000p在ubuntu20.04未找到wifi适配器,安装rtl8852ae网卡驱动问题解决方案
  20. Java实现第八届蓝桥杯兴趣小组

热门文章

  1. lio linux工具,LIO介绍
  2. 二值形态学之击中击不中变换
  3. 干货!最全羽毛球技术动态分解gif图
  4. ANSYS APDL学习(3):ANSYS APDL 导入x_t格式模型并受力分析范例
  5. Python——列表的方法
  6. 【实验五 一维数组】7-6 sdut- C语言实验-数日子
  7. html div background-image,css3背景background-image
  8. 1.2 SpringBoot构建Docker镜像并推送到Harbor
  9. 想想搭建个域控文件打印机服务器
  10. Client does not support authentication protocol requested by server; consider upgrading MySQL client