如何保护移动应用的API(私钥)

Jor*_*416 13 security api web-services key ios

我正在构建一个必须只能用于iOS应用程序的Web服务.在未来,我想扩展到移动网站,使我的服务也可用于其他移动操作系统.

现在,我通过API完成所有工作.我的用户可以注册,搜索公司,从这些公司订购产品并跟踪他们的订单.它尚未活跃,但它正在运作..

我面临一个主要问题:如何确保这一点?

在过去的几天里,我已停止编码,我一直忙于搜索网络,StackOverflow和信息安全,以了解如何执行此操作.我发现亚马逊获取API的方式对我来说是最好的解决方案.亚马逊确保其服务的方式在这里解释.我已经为我的服务稍微调整了一下:

  1. 用户注册并获取私有API密钥+公共(标识)密钥
  2. 用户输入凭据并点击"登录".应用程序从变量+私钥创建哈希.App将变量+时间戳+哈希+公钥发送给API
  3. API查找数据库中的公钥,查找属于该公钥的私钥(如果公钥有效).然后API以与应用程序相同的方式创建哈希.如果哈希值相同,则执行请求(在这种情况下登录).

这种保护服务的方式对我来说很有意义,我可以编写大部分代码.但我有一个主要问题,我找不到任何解决方案:

  • 用户在创建帐户时获取公钥和私钥API密钥.公钥可以从服务器发送到用户设备,因为这不一定是秘密.由于私有API密钥永远不能通过网络发送,我怎么能确保登录用户设备的帐户知道在服务器上创建的私有API密钥?

有谁知道如何解决这个问题?任何帮助将非常感谢!!

Rot*_*mon 5

我认为你的身份验证方案过于复杂.我建议使用像oauth2这样广泛使用的协议来保护你的API - http://oauth.net/2/.
有许多客户端库和许多服务器端插件支持和实现它,并且可以轻松集成到您的应用程序中.


Bil*_*ill 5

以下是我解决同样问题的原因以及为什么我认为您的实际问题与您认为的问题不同:

亚马逊的做法有道理,安全,并且比oAuth更容易实现,所以我不确定为什么每个人都建议使用它.我使用亚马逊方法,如下所示:

  1. 用户注册使用API​​.我们确保生成公钥,密钥,保存联系人电子邮件,角色(我们的角色是"admin"和"user"),然后将API用户设置status为活动状态.这允许我们在服务器上管理基于角色的权限(速率限制,访问控制等)并随时停用帐户
  2. 我们将客户端ID和密钥发送回客户端.没有办法绕过这个,所以你通过以下方式使其尽可能安全:
    • 只发送一次令牌.如果用户忘记了他们的令牌,他们需要注册一个新的API客户端
    • 确保所有请求都是通过HTTPS进行的,没有例外 - 这使得任何嗅探流量都被加密,攻击者只有一次拦截
    • 加密数据库中的令牌.不要哈希它,因为它需要是可逆的.如果您使用AES-256加密时安全地存储加密密钥并生成新的随机IV(初始化向量),则攻击者将无法检索客户端密钥(理论上,如果您正确保护该密钥,即使不是它花了你一些时间来停用受损的客户端令牌).您在生成时将纯文本令牌发送到客户端,但它到达数据库之前对其进行加密.
  3. 当客户端发出请求时,他们会发送标头和已签名的请求.在您的服务器上,您可以找到与客户端ID关联的加密令牌,对其进行解密,然后计算签名并将其与发送的内容进行比较.如果您的计算签名和他们的签名匹配,那么您将继续请求.

就像我说的那样,没有办法将私有令牌发送给客户端,但好处是你只做了一次,而且无论如何都应该通过SSL.

您缺少的问题是如何在设备上保护该令牌.这是另一个我没有看到任何解决方案的问题.

这两种情况唯一可行的选择是:

  1. 您在服务器上为每个客户端生成一次私有令牌,并且只将其一次性发送到客户端(没有提醒,只有像亚马逊那样的总重置)
  2. 除了将令牌存储在设备本身之外,您实际上无法做任何事情.

我们提出的用于在设备上保护令牌的一个措施是实际上定期旋转令牌.因此,例如,您可以将令牌存储在设备上,供每个用户使用,也可以硬编码到应用程序中.您经常需要为设备添加新令牌.如果您有一个硬编码令牌,那么您使用新的硬编码令牌更新应用程序,当用户通过他们的应用商店更新时,他们将自动获得新令牌.然后撤销所有X天的令牌并要求任何落后者更新应用程序.如果每个客户端在登录/注册时被赋予唯一令牌,则另一个选项是使令牌失效,然后在下次使用应用程序时自动将其注销.重新登录后,您将生成并发送一个有效期为X天的新令牌.

最后,这些是常见的一些问题,至少对于您正在使用的身份验证方法,我认为我还没有解决.因此,您真正做的最好的事情就是接受与发送和存储令牌相关的小风险,并将精力放在使API安全上.