Android对于请求数据安全的一些思考

我们Android端的数据请求很容易,通常都是使用Retrofit来实现的。

kotlin 复制代码
/**
 * 申请添加对方为好友。
 *
 * @param from 好友请求发起的用户id
 * @param to 被发起好友请求的用户id
 * @return 好友请求是否送达
 */
@POST("v2/friendRequestSend")
@FormUrlEncoded
suspend fun addFriendRequest(
    @Field("from") from: String,
    @Field("to") to: String
): Flow<ApiResult<Boolean>>

这是使用form表单请求的一种方式。这种请求很容易被伪造,从而绕开客户端做一些盗版的app。那么问题来了,怎么优化?

kotlin 复制代码
@POST("v3/friendRequestSend")
suspend fun addFriendRequestV3(@Body body: RequestBody): Flow<ApiResult<Boolean>>

在请求数据model类的基类中添加一个转换为RequestBody的方法。

kotlin 复制代码
fun toRequestBody() : RequestBody {
    return Gson().toJson(this).toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
}

先修改为RequestBody的请求方式,然后我们再对RequestBody做文章。

如何防止伪造数据

我们发出去的RequestBody是有一定玄机的,除了业务相关的字段,还应该添加一些公共字段。这些公共字段包括timestamp、random和signature等。先说签名,签名是针对对大部分字段对。将这些字段放入一个按key的字母排序的hashmap,先转为json字符串,再对json字符串做一些加密。这样服务端也对这些字段排序,并按同样的方式进行签名,然后比对客户端传入的数据有没有被修改。如果没有被黑客改过,很好,我们再接着做下一步校验。random是否是按照我们的特定算法随机出来的随机数,并非完全随机。如果不是,则说明不是由客户端签名出来的,直接拒绝请求。说到这里,有些人可能会动脑筋,我抓包,直接按你的数据发送请求不就好了?对不起,平台就是可以为所欲为的。你的签名过期了,我不认!你能把我怎么着?这时timestamp就派上用场了,当然这个还要考虑时区。如果我服务端收到请求的时间减去客户端签名时的时间戳,发现竟然过了整整3秒钟。这时服务端则认为,你是不是穿越过来的?都什么年代了,网速竟然可以如此之慢!

如何防止请求数据泄露

如果你的app对请求的安全级别更高,那么你就要使用RSA非对称加密了。生成一个RSA密钥对,即公钥和私钥。这些业务相关的字段就不要传了,先将其转换为json字符串,然后使用RSA的公钥对其进行加密,再传给服务端。服务端使用相对应的私钥对数据进行解密。注意私钥请妥善保管,不要泄露。

###服务端的大致实现

java 复制代码
Req req = new Req("1", "3", "2");
List<String> list = new ArrayList<>();
// 签名数据后面加进去
list.add("signature");
// 创建一个HashMap并添加一些键值对
Map<String, Object> hashMap = new HashMap<>();
Field[] fields = req.getClass().getDeclaredFields();
for (Field field : fields) {
    field.setAccessible(true);
    if (list.contains(field.getName())) {
        continue;
    }
    try {
        hashMap.put(field.getName(), field.get(req));
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

// 将HashMap的键按字母顺序排序
List<String> sortedKeys = new ArrayList<>(hashMap.keySet());
Collections.sort(sortedKeys);

// 创建一个新的按键排序的HashMap
SortedMap<String, Object> sortedMap = new TreeMap(hashMap);

// 将排序后的HashMap转为JSON字符串
// 创建ObjectMapper对象
ObjectMapper objectMapper = new ObjectMapper();

// Jackson生成Java对象为JSON字符串
String jsonString = null;
try {
    jsonString = objectMapper.writeValueAsString(sortedMap);
} catch (JsonProcessingException e) {
    e.printStackTrace();
}
// 解析JSON转为对象
sortedMap.put("signature", encryptToMD5(encryptToAES(jsonString)));

// 签名数据
System.out.println("signature="+encryptToMD5(encryptToAES(jsonString)));

总结

数据安全攻防是一个持续对抗的问题。树大招风,树欲静而风不止。你的平台如果要做大做强,必然要将数据安全放在非常重要的位置,可以说是一个企业的命脉。对数据多做几层加密,养兵千日,用兵一时。一旦有人发出攻击,哪怕复杂度再高一点点,那就对你没有办法。最后祝大家,技术更上一层楼,多多学习新技术,技术的更新换代很快,如果不思进取,则可能在时代的潮流中被淘汰。

相关推荐
cdprinter3 分钟前
信刻——安全生产音视频录音录像自动刻录备份归档管理系统
安全·自动化·音视频
代码s贝多芬的音符24 分钟前
ios android 小程序 蓝牙 CRC16_MODBUS
android·ios·小程序
二宝1521 小时前
黑马商城day4-微服务02
微服务·云原生·架构
嘉里蓝海3 小时前
橙色风暴中的安全守卫者——嘉顺达蓝海的危险品运输启示录
安全
百锦再3 小时前
对前后端分离与前后端不分离(通常指服务端渲染)的架构进行全方位的对比分析
java·开发语言·python·架构·eclipse·php·maven
2501_915918413 小时前
iOS 混淆实战 多工具组合完成 IPA 混淆、加固与工程化落地(iOS混淆|IPA加固|无源码混淆|Ipa Guard|Swift Shield)
android·ios·小程序·https·uni-app·iphone·webview
雨白3 小时前
让协程更健壮:全面的异常处理策略
android·kotlin
Blossom.1183 小时前
把AI“刻”进玻璃:基于飞秒激光量子缺陷的随机数生成器与边缘安全实战
人工智能·python·单片机·深度学习·神经网络·安全·机器学习
Jeled4 小时前
AI: 生成Android自我学习路线规划与实战
android·学习·面试·kotlin
wuyunhang1234564 小时前
Docker----快速入门
docker·容器·架构