一、使用HTTPDNS,防止DNS劫持
为确保用户端APP与正确的服务器进行通讯,我们使用HTTPDNS解析服务。传统的DNS解析服务容易遭到DNS劫持,使用HTTPDNS解析服务,让APP直接通过IP地址与服务器进行通讯,而不是通过域名与服务器通讯,保障了通讯安全。现有提供HttpDNS解析服务的有以下几家,可以看下他们的官方产品说明文档:
腾讯云:https://cloud.tencent.com/document/product/379/3519
阿里云:https://www.aliyun.com/product/httpdns
二、使用HTTPS,确保数据传输安全
使用HTTPS的好处就不多说了,现在几乎是有大型平台已经全部使用HTTPS协议了,而且SSL证书也在几家大的云服务提供商那都可免费申请
三、使用URL签名,确保请求的唯一性
假设请求数据如下
{
"head":{"method":"list","version":"1.0"},
"body":{"type":"info"}
}
在不加URL签名的情况下,任何人获取上面请求数据后就能够对服务器发起请求,如果使用URL签名,请求数据如下:
{
"head":{"method":"list","version":"1.0"},
"body":{"type":"info"},
"timeStamp":1425065977,
"sign":"607a0aa16db850d06682d7711588ae46"
}
这里多了2个参数,timeStamp是APP发起此次请求的服务器当前时间,sign是根据timeStamp的数值,按MD5算法或其它算法生成的效验码。timeStamp和sign是一一对应的关系,如果timeStamp的值变了,则sign的值也随之变动。服务器端收到APP发的请求后,首先比较timeStamp的数值与服务器收到该请求的时间,当两者相差比较大(如相隔了60秒),则可能是黑客发起的非正常请求,服务器对此请求不予处理;如两者相差在允许范围内,则验证用timeStamp的数值按APP端同样的算法,生成的字符串内容是否和APP发送的sign内容一致。
sign = md5(body + timeStamp + 效验密钥 )
此处假设效验算法为body + timestamp + 效验密钥,进行的MD5算法
加上URL签名后,服务器会对请求数据进行效验,对合法的请求进行处理,非法的请求进行丢弃。使用此方法,需要APP端和服务器端的时间保持同步。此处在请求效验失败的情况下,服务器可以返回服务器时间,APP端进行时间比较,然后在计算”timeStamp”的数值时,需要把两者的差值也计算在内。效验出错,服务端返回代码:
{
"code":"9999",
"msg":"",
"data":{"timeStamp":1425065977}
}
四、使用协议加密,杜绝明文请求
1、如果使用明文传输数据,会导致数据在传输过程中数据被窃取的风险,所以我们需要对传输的数据进行加密处理。
2、一般需要对数据进行加密传输的情况发生在需要用户登录才能查看的用户数据。这里,对于用户私密数据,需要将签名密钥动态化,以确保数据安全。签名密钥一般在用户登录验证通过后服务器返回给客户端APP。服务端和APP都保留此密钥对数据进行签名,然后协商一种加密模式对明文数据进行加密传输。
4.1、登录请求处理,获取密钥
登录请求URL为:https://api.test.cn/login/
请求主体
{
"head":{"method":"list","version":"1.0"},
"body":{"username":"user","pwd":"13154649878"},
"timeStamp":1425065977,
"sign":"607a0aa16db850d06682d7711588ae46"
}
服务器返回:
{
"code":"0",
"msg":"",
"data": {"accountToken":"abcdefg","accountId":"123456"}
}
服务器保存和维护accountToken accountID 与用户的映射,并设定和维护accountToken的过期时间。服务器收到APP的数据请求后,通过accountId提取accountToken,如果accountToken在有效期内,则延迟有效期,并对请求数据进行签名验证,如果accountToken过期,则需要重新登录获取accountToken。
accountToken:APP端使用,负责对传输数据进行加密解密
accountId:APP传递给服务端,用于服务器检索当前请求的加密解密key
以上传递的用户名密码和返回的token都是明文的,采用的是公开数据的请求模式,用户信息和data数据又被窃取的风险,为了保障数据安全需要对请求数据和返回数据进行加密处理。请求数据如下:
请求主体
{
"head":{"method":"list","version":"1.0"},
"body":"加密数据",
"timeStamp":1425065977,
"sign":md5(body加密数据 + timeStamp + 效验密钥 )
}
服务器返回:
{
"code":"0",
"msg":"",
"data":"加密数据"
}
处理数据加密算法,可以采用对称加密或非对称加密算法,加密密钥可以协商一个方案,比如根据timeStamp计算出一个Key,对数据进行加密,服务器返回数据后根据这个密钥进行解密。或者使用非对称加密算法,客户端使用公钥对数据进行加密解密,服务器使用私钥对数据进行加密解密。
4.2、后续请求处理
登录请求URL为:http://api.test.cn/useinfo/
请求签名,sign = md5(params + timeStamp + accountToken)
{
"head":{"method":"list","version":"1.0"},
"body":"加密数据",
"accountId":"123456",
"timeStamp":1425065977,
"sign":md5(body加密数据 + timeStamp + accountToken)
}
app端,根据登录效验获得的accountToken,对请求body数据进行加密并签名,服务器接受到请求,通过accountId找到对于的accountToken,然后根据timeStamp和accountToken对sign进行效验,数据效验通过,将使用密钥对请求body进行解密,然后处理请求,并返回数据
{
"code":"0",
"msg":"",
"data":"加密数据"
}
服务器返回数据,使用accountID对应加密key和加密算法进行解密。
4.3对称加密
4.4非对称加密
五、app应用加固,防止反编译
以上数据安全加密使用的密钥都存储在APP内部,一旦APP被反编译,或者内存能够被读取,就会导致信息泄露,所以需要对APP应用打包的时候进行安全加固,这里可以采用第三方平台通过的服务进行安全加固。
阿里云:https://help.aliyun.com/document_detail/35050.html
腾讯云:https://cloud.tencent.com/product/ms?idx=2
网易:http://dun.163.com/product/android-reinforce