移动端(iPhone)应用向ASP.Net Web API发出请求的身份验证(针对我的设计提供反馈)

50
我正在设计一个网站,将拥有一个移动设备的配套应用程序(最初仅面向 iPhone)。该网站将是一个 ASP.Net MVC 3 应用程序,我还将拥有一个 ASP.Net Web API 网站(MVC 4),以向 iPhone 应用程序公开服务。iPhone 应用程序将拥有自己的表单,从中获取用户名和密码并将其发送到带 JSON 标头的 Web API 中。
我希望从一开始就考虑安全性,而不是事后再考虑。尽管我绝非安全专家,但我已经做了很多研究,看看其他人如何处理来自 Web 服务的移动应用程序客户端的身份验证。我认为我想出了一个不涉及第三方 OAuth 的好方法。
非常感谢您提供的任何和所有意见、建议、批评和一般的 WTFs :)。
我最大的关注点是:
1.确保对 Web API 进行的调用得到授权
2.最小化重放攻击的风险(因此在下面的调用中使用了时间戳)
iPhone 应用程序将开发如下:
两个字符串被硬编码到 iPhone 应用程序中(每个用户相同的值):
1. 应用程序ID: 用于标识访问 Web API 的客户端类型 (iPhone、Android、Windows Phone 等)的字符串。
2. 应用程序散列盐: 用于用户无关请求的哈希的字符串。
两个字符串存储在 iPhone 应用程序的本地数据库中(每个用户的唯一值):
1. API 用户访问令牌: Web API 在成功验证后提供给客户端的字符串(token),允许客户端访问 Web API 而不需要在每个请求中发送用户名和密码。
2. 用户散列盐: 用于针对已建立用户账户的请求的哈希的字符串。
iPhone 将以以下方式进行调用:
API 方法:创建帐户
客户端发送:
- 新帐户数据 (用户名、密码、名字、姓氏等) - 应用程序 ID - UTC 时间戳 - 使用应用程序的散列盐加密的 UTC 时间戳 + 应用程序 ID 的哈希值
API 返回:
- 新用户散列盐
这里的想法是,在创建帐户时,可以使用应用程序的硬编码盐,因为如果该盐泄漏出去(通过反编译或其他方式),它并不会构成巨大的安全风险。但对于访问和修改用户数据的方法,我将使用仅属于该用户的盐,因此攻击者不能使用该盐来冒充其他人。
API 方法:获取帐户
(用于获取在网站上创建但尚未在 iPhone 上同步的用户散列盐。当用户尝试在 iPhone 上登录并且 iPhone 检测到它没有该用户名的记录时会发生这种情况。)
客户端发送:
- 用户名 - 密码(使用应用程序的散列盐哈希) - 应用程序 ID - UTC 时间戳 - 使用应用程序的散列盐加密的 UTC 时间戳 + 应用程序 ID 的哈希值
API 返回:
- 存在的用户散列盐
API 方法:登录(验证)
客户端发送:
- 用户名 - 密码(使用用户散列盐哈希) - 应用程序 ID - UTC 时间戳 - 使用用户散列盐加密的 UTC 时间戳 + 应用程序 ID 的哈希值
API 返回:
- API 用户访问令牌
API 方法:任何命令(即创建帖子,更新配置文件,获取消息等)

你的问题对我很有帮助,Joe,因为我正在尝试做类似的事情。不过我有一个问题——当用户创建账户时,你会发送未经哈希处理的用户名和密码。这似乎没问题,因为只有一次。但如果手机尝试登录已经创建的账户,你会使用应用程序盐值对他们的用户名和密码进行哈希处理。这真的比再次发送未经哈希处理的信息更安全吗?我的意思是,我知道这样做会更好一些,但两次发送未经哈希处理的信息并没有比一次更不安全。或者我漏掉了什么? - Andrew B Schultz
@AndrewBSchultz,你是对的,我最终没有在第一次调用时进行加密。由于它是SSL协议,并且该初始调用仅发生一次,暴露的风险可以忽略不计。 - Stoop
1
发送“未经哈希处理”的信息多次是不安全的。但真正的重点是整个API都受到SSL保护,因此所有传输都是加密的。从服务器传递用户的salt到客户端是有问题的。这样做的意义是什么呢?除其他外,这意味着您在多个位置计算密码哈希,当您发现现有的哈希算法已经被破解时(最终会发生),这使得升级密码哈希算法变得非常困难。只需传递使用SSL保护的用户名和密码,让服务器进行哈希处理即可。 - Craig Tullis
3个回答

4
在 VS 2013 中,您可以使用 “Asp MVC SPA Application” 模板生成一个可工作的实现,该实现会在登录时生成一个 Oauth2 令牌承载者,并使用 [Authorize] 属性对 WebApi 控制器调用进行授权。它使用 Membership 和 Entity Framework 在 SQL Server 中本地存储用户和哈希值。只需删除您不需要的 asp mvc 部分并保留 Auth 部分以供 WebApi 使用即可。更多详细信息请参见: http://msdnrss.thecoderblogs.com/2013/09/understanding-security-features-in-the-spa-template-for-vs2013-rc/

4

3

我的建议

  1. 认证与授权。将其构建在2个不同的服务器上(在某些项目中我也使用了3个服务器)。反向代理服务器在这方面非常好用。在一个服务器上进行认证,在另一个服务器上进行授权。

我认为这是在移动安全中使用Web API所需的最重要的步骤。

  1. 封装所有内容。

  2. 对于所有安全信息,请使用SSL。在我的情况下,我几乎所有情况都使用它。

  3. 为您的时间戳选择一个合适的时间以进行授权。不要将此时间段设置得太短,否则您的应用程序将变得缓慢,也不要设置得太长,因为网络嗅探器可以访问数据包。

如果您想要一个三服务器架构,请使用应用程序密钥来生成访问密钥(从服务器1生成)。此访问密钥将用于验证您的请求,在成功验证后(从服务器2),您可以使用该密钥从另一台服务器(服务器3)授权您的请求。

您提到的请求是标准规范。并没有看到什么问题。


1
我不得不查找反向代理服务器。有趣的概念,我会进一步探索。“封装一切”是什么意思? - Stoop
您将创建的ASP.Net Web API不会暴露除您提到的公共API之外的任何内容。我们已经遇到了很多让我们感到惊恐的开发人员。 - S.P.
在我们的情况下,我们使用nginx作为反向代理。它非常稳定和非常快速。 - S.P.
谢谢提供的信息。我会进一步研究有关反向代理的内容。从您的第一篇帖子中,当您说“封装一切”时,您是指什么?您是否指的是将与API调用一起发送的数据(模型)(例如Put)?如果是这样,那么应该将该数据封装在什么中?消息将以JSON格式传输。 - Stoop
是的,封装数据模型。您还需要加密应用程序 ID。是的,JSON 对此非常完美。 - S.P.

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