当前位置: 首页 > 知识库问答 >
问题:

REST Web服务身份验证令牌实现

尹俊雅
2023-03-14

我正在使用C#实现一个REST web服务,它将作为云服务托管在Azure上。因为它是一个REST服务,所以它是无状态的,因此没有cookie或会话状态。

Web服务只能通过HTTPS(由StartSSL. com提供的证书)访问。

用户成功登录服务后,他们将获得一个安全令牌。该令牌将在未来的通信中提供身份验证。

令牌将包含客户端的时间戳、用户ID和ip地址。

所有通信都只能通过HTTPS进行,所以我不担心令牌被拦截并用于重播攻击;代币无论如何都会过期。

由于这是一项面向公众的服务,我担心有人可能会注册该服务,登录,然后修改他们收到的令牌,以访问其他用户的帐户。

我想知道如何最好地保护令牌的内容,并验证其未被篡改。

我计划执行以下操作以保护令牌:

客户端成功登录到该服务,该服务执行以下操作:

  1. 生成一个随机值,并用SHA256对其进行1000次哈希

当客户端调用服务时,它会将未加密JSON包中的加密令牌和签名发送给服务。这项服务将

  1. 从私钥哈希随机值重新创建会话密钥
  2. 用私钥验证签名
  3. 使用哈希化的会话密钥解密令牌
  4. 检查令牌没有过期
  5. 继续请求的操作...

我对加密一无所知,所以我有一些问题:

  1. 这是足够的还是过火了
  2. 我读到,为了检测篡改,我应该在令牌中包含一个HMAC。既然我用私钥签名,我还需要HMAC吗
  3. 我应该使用Rijndael而不是RSA吗
  4. 如果首选Rijndael,是否需要生成的IV进行解密?i、 e.我可以把它扔掉吗?还是需要将它发送给加密令牌?e、 g.加密令牌HMAC IV散列随机值

由于所有通信都通过HTTPS进行,未加密的JSON包在到达客户端之前并不真正未加密。

此外,我可能希望以后在PHP中重新实现该服务,所以这一切都需要在PHP中实现。

谢谢你的帮忙

共有1个答案

郝峰
2023-03-14

你真的对令牌想得太多了。老实说,最好的令牌安全依赖于随机性,或者更准确地说,不可预测性。最好的令牌完全是随机的。你是对的,一个担忧是用户会修改他/她的令牌,并用它来访问其他人的账户。这是一种常见的攻击,称为“会话窃取”。当令牌在服务器端随机生成并过期时,这种攻击几乎是不可能的。使用用户的信息,如知识产权和/或时间戳,是不好的做法,因为它提高了可预测性。我在大学里做过一次攻击,成功地猜测了基于服务器时间戳的活动令牌,时间是微秒。应用程序的作者认为微秒会变化得足够快,以至于它们是不可预测的,但事实并非如此。

您应该知道,当用户在代理服务器后面时,代理有时会以纯文本查看他们的SSL请求(出于安全原因,许多代理会执行深度数据包检查)。因此,您过期会话是件好事。如果您没有这样做,您的用户将容易受到这样的攻击,也可能受到XSS和CSRF的攻击。

RSA或Rijndael应该足够了,只要有合理的密钥长度。此外,你应该使用带有令牌的HMAC来防止篡改,即使你正在签名。理论上,这是多余的,因为你是用私钥签名的。然而,HMAC经过了很好的测试,你对签名机制的实现可能有缺陷。因此,最好使用HMAC。你会惊讶于有多少“自己卷”的安全实现有缺陷,导致它们妥协。

听起来你对安全很在行。继续努力!在这个世界上,我们需要更多有安全意识的开发者。

编辑:

在令牌中包含时间戳/用户ID被认为是安全的,只要它们使用只有服务器拥有的强对称密钥(如AES、Blowfish等)进行加密,并且只要令牌包含一个防篡改散列,例如HMAC,它与用户ID/时间戳一起使用密钥加密。哈希保证完整性,加密保证机密性。

如果加密中没有包含HMAC(或其他哈希),则用户可能会篡改加密的令牌,并将其解密为有效的内容。我在一台服务器上进行了一次攻击,其中用户ID和时间戳被加密,并被用作没有散列的令牌。通过更改字符串中的一个随机字符,我可以将用户ID从58762更改为58531。虽然我无法选择“新”用户ID,但我可以访问其他人的帐户(这是在学术界,作为课程的一部分)。

另一种方法是使用完全随机的令牌值,并在服务器端将其映射到存储的用户ID/时间戳(它位于服务器端,因此不受客户端控制)。这需要更多的内存和处理能力,但更安全。这是你必须根据具体情况做出的决定。

至于从IV和其他钥匙中重复使用/衍生钥匙,这通常是可以的,前提是这些钥匙只在短时间内有效。从数学上讲,不太可能有人能打破它们。然而,这是可能的。如果你想走偏执路线(我通常会这样做),随机生成所有新密钥。

 类似资料:
  • 除了用户名和密码(例如来自ACS的令牌)之外,是否还有其他使用AMQP对Azure服务总线进行授权的方法? 在我的场景中,我希望能够在不公开凭据的情况下为资源级客户端提供对服务总线的访问权限。

  • 将有一个Angular JS客户机应用程序,它将需要发送用户名和密码,并从应用程序获取令牌,以便在顺序请求中使用。在某些时候,可能也会有Android客户端访问此web服务。 我假设Spring Security在内部将令牌映射到用户会话,这意味着它知道令牌XXXXXXXXXXXX是管理用户Bob,令牌AAAAAAAAAA是标准用户Joe。然而,我对Spring Security没有太多的经验,所

  • 我有一个LaravelAPI(实际上是LumenAPI)服务于VueJS前端。Vue应用程序允许用户登录到谷歌。然后将Google令牌发送回Lumen API,后者使用Google验证令牌,然后验证电子邮件地址是否为有效用户。然后它生成一个令牌,与用户一起存储在数据库中,并返回用户对象。 我没有使用Passport或jwt auth之类的东西。那么现在,我如何使用默认的Auth中间件来验证(现在已

  • 问题内容: 在使用Java EE 6的Web应用程序上,我想将某些功能作为Json Rest Service公开。我想使用身份验证令牌进行登录,用户将发送其用户名,密码,服务器将发送回令牌,该令牌将用于授权用户在给定时间内的进一步请求。 到目前为止,有几个问题困扰着我; 当服务器创建令牌并将其发送给客户端时,服务器是否应该使用像哈希表这样的东西作为用户ID令牌对将其保存在DB或Bean中? 我可以

  • 我想扩展现有的迁移工具,以便在将文件导入到 SharePoint Online 之前对文件设置敏感度标签。我找到了微软信息保护SDK,它似乎提供了必要的API。 为了熟悉API,我下载并运行了ServicePrincipalAuth示例应用程序(请参见https://learn.microsoft.com/en-us/samples/azure-samples/mipsdk-dotnet-file