我正在设计一个网站,将拥有一个移动设备的配套应用程序(最初仅面向 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 方法:任何命令(即创建帖子,更新配置文件,获取消息等)
我希望从一开始就考虑安全性,而不是事后再考虑。尽管我绝非安全专家,但我已经做了很多研究,看看其他人如何处理来自 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 方法:任何命令(即创建帖子,更新配置文件,获取消息等)