我正在设计一个网站,其中将有一个移动伴侣(仅限初始iPhone)。该网站将是一个ASP.Net MVC 3应用程序。我还会有一个ASP.Net Web API站点(MVC 4)来向iPhone应用程序提供服务。 iPhone应用程序将拥有自己的表单来捕获用户的用户名和密码,并将其发送到JSON标头中的Web API。验证从移动(iPhone)应用程序到ASP.Net Web API的请求(我的设计请求提供反馈)
我想从一开始就考虑安全性,而不是一想到以后。 我不是一个安全专家。我已经做了大量的研究,以了解其他人如何从Web服务处理移动应用程序客户端的身份验证。我想我已经想出了一个体面的解决方案,不涉及到第三方oAuths。
我会非常感谢您提供任何意见,建议,批评和一般的WTF。 :)
我最大的担忧是:
- 确保到Web API的调用被授权
- 最大限度地减少重放攻击的风险(因此时间戳在下面的调用)
iPhone应用程序将如下开发:
两个字符串被硬编码到iPhone应用程序中(每个用户的值相同):
- 应用程序ID
这是一个用来识别客户端在访问网络API(在iPhone,Android,Windows phone的,等等)的类型的字符串。 - 应用程序的散列盐
这是一个字符串,用于对用户不可知的请求进行盐散列。
两个字符串存储在iPhone应用程序的本地数据库(唯一的每个用户的值):
- API用户访问令牌
这是提供给客户一个字符串(令牌)通过Web API验证成功后,允许客户端访问Web API,而无需在每个请求中发送用户名和密码。 - 用户散列盐
这是用来盐哈希针对建立用户帐户的请求字符串。
iPhone将在以下几个方式调用网络API:
API方法:创建帐户
客户端发送:
- 新帐户数据(用户名,密码,名字,姓氏等)。
- 应用程序ID
- UTC时间戳
- UTC时间戳+应用程序ID的哈希加盐与应用的散列盐
API返回:
- 新用户的散列盐
这里的想法是,在创建帐户时,我可以使用应用程序的硬编码盐,因为如果盐(通过反编译或其他方式)出来,它不是一个巨大的安全风险。
但是,对于访问和修改用户数据的方法,我将使用仅由该用户拥有的salt,因此攻击者不能使用它来模拟其他用户。
API方法:获取帐号
(用于获取用户的散列盐用于在网站上创建的,但尚未同步iPhone上的帐户会发生这种情况,当用户尝试。登录iPhone和iPhone会检测到它没有该用户名的记录。)
客户端发送:
- 用户名
- 密码(散列与应用程序的散列盐)
- 应用程序ID
- UTC时间戳
- 哈希UTC时间戳+应用程序ID与应用程序的散列盐腌盐
API返回:
- 现有用户的散列盐
API方法:登录(认证)
客户端发送:
- 用户名
- 密码(散列与用户的散盐)
- 应用ID
- UTC时间戳
- 哈希UTC时间戳+应用程序ID与用户的散列盐盐渍
API返回:
- API用户访问令牌
API方法:任何命令(即创建后,更新个人资料,获取信息等)
客户端发送:
- 命令数据
- API用户访问令牌
- 应用ID
- UTC时间戳
- 散列UTC时间戳+应用程序ID + API用户访问令牌用户散列盐盐渍
你的问题是帮助我乔,因为我试图做同样的事情。我有一个问题 - 当用户创建一个帐户时,你发送用户名和密码而不用散列它们。看起来很好,因为它只是一次。但是,如果手机试图登录已创建的帐户,则可以使用应用盐对用户名和密码进行哈希处理。这真的比再次发送它更好吗?我的意思是,我知道这样会好一点,但是发送两次未反映的信息并不比发送一次更不安全。或者我错过了什么? – 2012-10-19 12:45:16
@AndrewBSchultz,你是对的,我没有加密那个第一个电话。由于它是SSL,并且由于最初的通话只发生一次,所以暴露风险可以忽略不计。 – Stoop 2012-12-08 00:50:39
任何次数发送“unhash”信息都是不安全的。但真正的意义在于,整个API都受到SSL保护,因此所有传输都是加密的。将用户的盐从服务器传递到客户端是值得怀疑的。这是什么意思呢?除此之外,这意味着你在多个地方计算密码哈希值,当你发现现有的密码哈希算法被破坏(并且最终你会)时,很难升级你的密码哈希算法。只需传递用SSL和SSL保护的用户名和密码,然后让服务器执行哈希。 – Craig 2013-06-24 15:18:01