如何在APK文件中保护API安全性

3
我目前正在开发一个与我运营的网站相关的api。该api将在多个地方使用,其中之一是安卓应用程序。
它的目的是允许用户登录并下载文件。我已经构建了api,并且它将使用HTTPS,因此在传输数据时所有数据都是安全的。
我遇到的问题是API调用需要一个API密钥。有了这个密钥,您就可以访问API的某些功能,这可能会引起问题。
我想知道的是,有没有一种方法来保护这个API密钥?我根本不是安卓开发人员,但将使用API的人将在安卓上,所以我需要找出一个解决方案。
下面是API使用的流程示例:
// Log the user in with their username and password (HTTPS, so not really an issue)
romhut.request('/api/users/login?apikey=KEY', {username : 'scott', password : 'password'}, function(r) { 

    console.log(r);

    // Once you have the token, request the API key that allows actions such as downloading
    romhut.request('/api/files/download?apikey=KEY', {token : r.token, file : file}, function(d){

        console.log(d);
        // Download the file

    }, 'POST');

}, 'POST');

你想要离线存储API密钥,还是在登录后运行时检索? - BitParser
API密钥由开发人员提供,该密钥从用户那里返回一个令牌,然后可以使用该令牌进行请求。 - Scottymeuk
我已经更新了我的示例。让用例更简单了一点。 - Scottymeuk
您对此问题还有其他需要了解的信息吗? - argentage
3个回答

2
你应该为每个用户创建一个特定的API密钥。实际上,没有真正有效的方法来保护实际在用户手中的数据(请询问副本保护制造商)。然后,您可以使用HMAC将API密钥和请求的API哈希在一起,并验证在两端发生相同的事情。参见:http://en.wikipedia.org/wiki/Hash-based_message_authentication_code(PHP有一个此类功能)。
实际上,更准确地说,密钥和用户之间应该是多对一的关系,因为您可能会为用户拥有不同且/或已撤销的密钥。
有关详细概述,请参见:https://security.stackexchange.com/questions/18572/is-it-okay-for-api-secret-to-be-stored-in-plain-text-or-decrypt-able

这就是关键所在。在登录后检索API密钥会是一个更好的解决方案,我个人认为。 - BitParser
问题在于,为了让用户能够登录,应用程序的开发人员需要提供他们的API。如果没有这个,任何人都可以从任何地方登录,而且无法跟踪应用程序正在做什么。这也意味着用户无法取消授权特定的应用程序。 - Scottymeuk
1
如果你想尝试限制人们使用哪个应用程序连接到你的服务,我认为你能做的最好的方法是在应用程序中存储一个全局密钥,并使用它来“验证”请求是否来自特定的应用程序。任何决心的人都可以提取该密钥,然后从任何地方登录(或发布该密钥以允许任何人从任何地方登录)。 - Michael
是的,这就是我遇到的问题。任何人都可以访问APK文件中的API密钥。我猜这就是它所能做的了。他们无法进行任何编辑操作,除非他们作为用户进行身份验证,而这只能通过用户名和密码进行(可能将来会取消这种方式)。 - Scottymeuk
无法避免 API 密钥可读取性 - 它作为加密密钥而非可哈希的密码在运作。 - argentage

2

不行。一旦将API密钥嵌入到Android应用程序中,就无法保护它。应用程序需要访问API密钥,因此拥有应用程序访问权限的人将能够从应用程序中恢复该密钥并将其用于自己的目的。你最好能做的是混淆你的应用程序,使得逆向工程变得更加困难(目标是使攻击者逆向破解你的应用程序比值得他花费的时间要困难)。你需要根据暴露API密钥的风险决定在这方面投入多少努力,但你永远无法使其不可恢复,只能使其更加困难。实际上,你最好的选择很可能是在构建过程中打开Proguard(这样在APK中就可以获得相当程度的混淆,而无需你进行额外的工作),然后希望一切顺利。


0

Android密钥库是一个值得关注的方向吗?然后,也许根据应用程序在安装时存储在Android密钥库中的密钥,将加密字符串发布到API。这样,如果成功解密,它就可以处理请求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接