JWT share/store 是否是在客户端和服务器上签名的秘密?

Does JWT share/store the secret for signing on both the client and server?

我正在解决一些与 JWT 身份验证安全性相关的架构问题,我正在尝试弄清楚以下内容:

  1. JWT 如何在服务器和客户端之间安全地传递秘密?

  2. 看看下面摘自 https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/ .................................

CSRF can be prevented by using synchronized token patterns. This sounds complicated, but all modern web frameworks have support for this.

For example, AngularJS has a solution to validate that the cookie is accessible by only your domain. Straight from AngularJS docs:

'When performing XHR requests, the $http service reads a token from a cookie (by default, XSRF-TOKEN) and sets it as an HTTP header (X-XSRF-TOKEN). Since only JavaScript that runs on your domain can read the cookie, your server can be assured that the XHR came from JavaScript running on your domain. You can make this CSRF protection stateless by including a xsrfToken JWT claim:'

{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["explorer", "solar-harvester", "seller"], "sub": "tom@andromeda.com", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }

  1. 客户端如何创建并发送包含 xsrfToken 声明的有效请求,除非它可以在包含声明后首先签署 JWT? (毕竟这个 xsrfToken 是用来防止 EvilBob 伪造请求的,对吧?)

有关我目前对 JWT XSRF 过程的理解的更多详细信息,请参见此处 http://spring.io/blog/2013/08/21/spring-security-3-2-0-rc1-highlights-csrf-protection/

  1. 我可以解释一下 Stormpath 是如何做到的,还有一些其他的方法。 Stormpath 在 JWT header 中包含一个 'kid' (key id) 字段,它是 API Key ID / Secret 对的标识符。 JWT 使用 Secret 签名,ID 存储在密钥 id 字段中。当 Stormpath 验证令牌时,它可以检索秘密。这适用于服务器和服务,但 从未 传递给客户端。使用客户端将单独的服务与秘密粘合在一起是非常不安全的。

  2. 客户端不应该生成 JWT,这需要在服务器上完成。服务器知道 XSRF 令牌并可以在 JWT 中对其进行签名并将其放入 cookie。

希望这些信息对您有所帮助!

文章似乎将此称为 "synchronized token pattern",但描述的解决方案更适合 Double Submit Cookies method rather than the Synchronizer Token Pattern

双重提交 cookie 涉及在 header 或 body 中发送 cookie 值以及将其与自动发送的浏览器 cookie 一起发送。如果您不支持 CORS,那么在 header 中设置令牌无论如何都是安全的,就像任何自定义 header 值一样(例如 X-Requested-With). This is because a custom header cannot be sent cross-domain in the first place, so verifying that it has transported from the client verifies that it is not from another domain already. As a defence in depth strategy, you can set it to a random value, as explained by this answer.

随机值不需要来自服务器,也不需要签名。它只需要由 CSPRNG 生成。如果生成 client-side,则应使用 window.crypto。服务器所做的只是检查 header 和 cookie 值是否匹配。

第三方域无法伪造请求,因为即使浏览器会自动从受害者的机器发送 cookie 值,攻击者也无法将值包含在 header 或请求 body.

使用同步器令牌模式生成 CSRF 令牌 server-side 并根据 session 存储。该值必须从每个表单提交中发送,并经过验证server-side它与存储的令牌匹配。