我为用户互相竞争的应用程序预测REST API服务。当然,其中一个主要问题是作弊攻击保护。
例如,应用程序发送此请求以为此方案添加新分数:
HTTP PUT /score
"value" => 72
"access_token" => XXXXXXX
然后,malefactor使用修改后的值生成相同的请求:
HTTP PUT /score
"value" => 9000
"access_token" => XXXXXXX
所以,这是漏洞。解决方案是以预定模式进行签名查询:
sig = hashF(params + salt)
其中盐为client_secret
。但对于Android,我可以反编译应用并复制client_secret
。我可以将client_secret
移动到本机代码,但它仍然是漏洞 - 任何人都可以使用我的本机库或反编译它。
我想用我的app证书的指纹。它可以在代码中使用。像这样:
PackageInfo info;
try {
info = getContext().getPackageManager().getPackageInfo("com.mypackage", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
return new String(Base64.encode(md.digest(), 0));
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
非常好,但是通过这段代码,我可以访问任何应用指纹。那么我可以用什么盐?
答案 0 :(得分:1)
正如您已经注意到的,由于平台的性质,您无法完全保护任何秘密。这只是添加保护层的全部内容。如果你的比赛是随意的,而且比赛没有太多,你已经拥有的是好的。
如果您正在使用真实资金或其他非常有价值的东西使您的应用程序成为目标,您至少需要使用用户身份验证来保护它。例如,用户登录到应用程序(对服务器的SSL请求) - >从服务器获取令牌 - >使用令牌签署请求。
至少那时您不需要在APK中存储任何需要发布新分数的内容。但要做到这一点真的很复杂,它仍然不是完全无懈可击的。有人真正想要的仍然可以设计它是如何工作的并伪造它。