我刚刚开始在.NET中开发我的第一个REST API.由于它将是无状态的,我将使用令牌进行身份验证:
基本思路(System.Security.Cryptography):
- AES用于加密+ HMACSHA256用于完整性
- 令牌数据将包含具有以下属性的对象:用户名,发布日期和超时
- 数据库将保存用户名,哈希密码和HMAC哈希
登录:
- 检查凭据是否有效(用户名,将哈希密码与db值进行比较)
- 如果为true,则加密数据对象
- 在生成的令牌上使用HMAC并将其存储到数据库
- 将令牌(没有HMAC)返回给用户(cookie/string)
请求需要身份验证的方法:
- 用户使用每个请求发送令牌
- 令牌被解密
- 如果它已过期,则错误
- 如果未过期,则使用HMAC并将用户名+生成的哈希与db值进行比较
- 如果db check valid,则对用户进行身份验证
我看待它的方式,这种方法有以下优点:
- 即使db是comprosmised,它也不包含实际的令牌(哈希不能被反转......)
- 即使攻击者有令牌,他也不能通过更新字段来增加过期,因为到期日期在令牌本身中
首先,我想知道这是否是一个好方法.
除此之外,我还没弄清楚,在服务器上存储AES和SHA256密钥的位置(我应该对它们进行硬编码吗?如果我将它们放入web.config或使用机器密钥,而不是在负载平衡服务器的情况下我有问题, ...).
最后,我在哪里存储AES IV向量,因为Crypto.CreateEncryptor需要它进行解密?这是否意味着用户必须在每次请求时发送令牌+ IV?
我希望这有任何意义,我提前感谢你的答案.
更新:
好的,现在我做了更多的研究并找到了解决方案:
- 令牌将包含最初指定的数据(用户名,发布日期和超时)
- 使用encrypt-then-mac生成令牌(它包括AES加密数据,用于身份验证的这两个值的IV向量+标记,使用HMACSHA265生成)
- 令牌标记将写入db
- 如果用户将进行身份验证:
- 标签有效(令牌认证)
- 数据可以解密
- 令牌尚未过期
- tag匹配数据库中写入的标记
- 用户未在数据库中被阻止(令牌失效)
- 密钥将存储在web.config单独的部分中.每个服务器上必须有相同的密钥(当然每个应用程序)
我没有使用FormsAuthenticationTicket,因为在.NET中存在以下问题: