【问题标题】:What is the preferred way of using AWS (specifically S3) from mobile apps?从移动应用程序使用 AWS(特别是 S3)的首选方式是什么?
【发布时间】:2014-05-10 20:38:46
【问题描述】:

直接在应用程序代码中添加 AWS 访问密钥和秘密密钥绝对不是一个好方法,主要是因为应用程序驻留在用户设备上(与服务器端代码不同),并且可以通过逆向工程来获取凭证,这可以然后被滥用。

虽然我到处都可以找到此信息,但我无法找到解决此问题的最终解决方案。我有哪些选择?我阅读了有关临时凭证的令牌自动售货机架构,但我不相信它会更好。如果我可以对密钥进行逆向工程,那么我可以对请求临时凭证的代码进行逆向工程。一旦我拥有一组访问 S3 的临时凭据,我就如同拥有密钥一样出色。我可以一次又一次地请求临时凭证,即使它们很快过期。总而言之,如果一个应用程序可以做某事,我可以像恶意用户一样做。如果有的话,TVM 在管理方面可能会更好一些(轮换凭证,以及在发生违规时更改密钥等)。请注意,我们可以对密钥设置相同的访问限制,就像我们计划在 TVM 临时凭证的情况下那样。

此外,如果亚马逊不希望人们直接在应用程序中使用密钥,他们为什么不在他们的 SDK 中阻止它,并强制执行 TVM 或正确的解决方案。如果你留下一条路,人们就会使用它。我看了几篇这样的文章,不知道为什么?:http://blog.rajbala.com/post/81038397871/amazon-is-downloading-apps-from-google-play-and

我主要来自网络背景,所以我对此的理解可能有点缺陷。请帮助我了解这是否更好,以及是否有一个完美的(或可能是好的)解决方案来解决这个问题。

PS:是否有 TVM 的 Rails 实现?

【问题讨论】:

  • 你最后用了什么?
  • @Jasper...我仍然不知道正确的方法。
  • @Jasper 我想我可能已经找到了解决问题的好方法。请查看我的回答,让我知道这是否能解决您的问题,或者您是否找到了更好的方法。

标签: android ios ruby-on-rails amazon-web-services amazon-s3


【解决方案1】:

在应用程序代码中嵌入 S3 密钥是非常危险的。任何人都可以轻松地从您的应用程序代码中获取该密钥(无需逆向工程或高技能集),即使该密钥已加密存储,它仍然会受到损害,只是有人需要更加努力(取决于您如何加密)。

我希望您了解使用临时凭证访问 Amazon(S3 等)资源的优势(主要是安全性 + 其他一些,如无应用更新等)。我认为您对从 TVM 获取临时凭证的过程以及这比在代码中嵌入密钥更安全的过程感到更加困惑。

每个使用 TVM 的客户首先需要注册您托管的 TVM 服务器实现。 App(使用 TVM 客户端)和 TVM 服务器之间的通信是通过 SSL 进行的。

首先应用程序通过提供 UUID 和密钥向 TVM 注册。请注意,密钥未嵌入应用程序代码中(我认为这是造成您混淆的主要原因),而是在注册时随机生成(使用SecRandomCopyBytes 生成加密安全随机字节数组)(和十六进制编码)。

一旦设备成功注册到 TVM,客户端 TVM 将生成的 UDID 和密钥存储在 iOS 中称为 Keychain 和 Android 中称为 Shared Preferences 的存储中。 iOS 中的钥匙串是 iOS 提供的共享存储,用于安全(加密)存储信息(主要是密钥、密码等)。

在注册和 UDID/Secret Key 存储后,App 可以通过发送 UDID、加密签名和时间戳从 TVM 获取令牌。加密签名是使用密钥从时间戳生成的HMAC hash。 TVM 可以使用 UDID 来查找密钥并使用它来验证签名。然后,TVM 通过发回临时凭据进行响应,这些凭据使用密钥(使用AES)进行加密。应用程序使用密钥解密临时凭证,然后可以使用它们来访问授权临时凭证的任何 AWS 服务。最终,这些临时凭证的到期时间将达到,此时应用程序可以根据需要获取新的临时凭证。

【讨论】:

  • 我要补充一点,临时凭据的另一个好处(除了它们是临时的并且不存储在客户端设备上的事实之外)是它们的范围有限。即这些凭据仅具有与 TVM 调用的角色相关联的权限(或子集)
  • @msk ...您在这里描述的是 TVM 和应用程序之间的安全通信,发布应用程序寄存器。我很清楚这一点,这不是风险(这是使用时间戳和密钥的哈希值来验证 URL 的通用/经过测试的方法)。我更关心的是什么会阻止某人使用新的 UDID 注册,并获得临时凭证,从而阻止 S3 访问。所有 TVM 服务器和客户端代码都是开源的,我认为使用新的 UDID 和密钥(+ 按照步骤)伪造来自应用程序的请求以获取一组新的临时凭据并不困难。
  • @sebsto....我们可以通过创建一个具有非常严格访问权限的新用户并使用该用户的密钥来做同样的事情。这里我不否认管理优势,但我并不清楚安全优势。我觉得我可以获得相同级别的访问权限(与 S3 访问密钥相关联),无论密钥是否在代码中。想法?
  • @amit_saxena TVM 就像所有其他安全措施一样,相对更安全,而不是 100% 安全。 TVM 方法绝对比在源代码中嵌入明文密钥(明文/加密)更安全,如果受到损害,您别无选择,只能更新应用程序。使用 TVM,您始终可以选择移除对某些 ID 的访问权限,并且无需更新应用程序。
  • AWS 引入了 Amazon Cognito——它在很多情况下取代了 TVM——但即使这样也会遇到同样的问题——你仍然必须在你的应用程序中嵌入 Cognito 身份池 ID——所以同样的问题。正确的解决方案是使用某种 APK 签名作为安全机制 - 但它不存在。
【解决方案2】:

我不确定签名 URL 与 TVM 的关系,因为我不理解 100% 的概念,但签名 URL 确实为我解决了这个问题。我需要一种机制来提供 Web 应用程序和移动应用程序数据,而不允许滥用凭据。将密钥放入代码中确实是一个非常糟糕的主意,因为它可能会为公司带来巨额账单。

经过 3 天的广泛研究,我找到了一个简单且看似可靠且相对安全的解决方案:签名网址。这个想法是,一个非常轻量级的后端可以生成一个临时 URL,该 URL 将授予用户在 有限时间 内访问特定资源。所以想法很简单:

  • 用户通过 Rest 调用向我们的后端询问他想要特定资源

  • 后端已获得 AWS S3 授权

  • 后端为用户生成一个临时 URL 并在 Rest 响应中发送

  • 用户使用 URL 直接从 AWS 获取数据

可以在here 找到即插即用的 Python 实现,并稍作修改,我不得不使用:here

当然要弄清楚的另一件事是我们如何在知道我们可以授予用户 URL 之前授权用户,但那是另一双鞋。

【讨论】:

    【解决方案3】:

    理想情况下,您应该使用Cognito Identity 以及适当的策略来实现这一目标。它应该在 iOS 和 Android SDK 中与 S3TransferUtilityS3TransferManager 一起使用。这也将允许后台上传和下载。 Cognito 提供访问 AWS 资源的临时凭证,并且是免费的。此外,如果您想要安全访问,您可以使用 UserPools 或 Google、Facebook 等提供商联合它。

    谢谢, 罗汉

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 2013-02-08
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多