快速会话中间件中的秘密的目的是什么?

What is the purpose of the secret in express-session middleware?

我正在阅读 express-session 自述文件,其中谈到了秘密:

This is the secret used to sign the session ID cookie. [...]

Using a secret that cannot be guessed will reduce the ability to hijack a session to only guessing the session ID (as determined by the genid option).

https://github.com/expressjs/session#secret

老实说:我不太明白。

我认为秘密的目的是与会话 ID 一起用作某种哈希函数的参数,以生成签名(如 hash(secret, sessionID) => signature)并将该签名附加到cookie 中的会话 ID 值。

因此,万一有人猜到了正确的会话 ID,它仍然无法工作,因为签名不匹配?

这个秘密到底是用来做什么的?

当出现这样的问题时,通常最好直接去看源代码,看看这个秘密是如何使用的。这是使用 open-source 代码的优点之一。

在 express-session 代码中,秘密用于对 cookie 的值进行“数字签名”,如您在 express-session 代码 here 中所见。这允许会话代码检测 cookie 值是否已被篡改,或者它是否仍然是服务器上最初设置的真实值,这使得它们在暴力会话攻击中更难“猜测”。

稍后(在代码 here 中)读取 cookie 值时,将检查该值以查看它是否已使用正确的密钥正确签名。如果不是,则丢弃 cookie 值(不使用)。

这是一种防止黑客编造自己的 cookie 值或修改 cookie 值的方法,因为只有使用适当的秘密签名的值才能测试为有效。

签名的过程还有一个附带的好处,就是它使值变得更长并且有点 random-looking,因此它掩盖了潜在的值,使其更难猜测。经典的例子是,如果底层会话 ID 只是一个单调递增的数字,那么很容易猜测未来或以前的会话值。但是,一旦它被签名,它就不再像一个简单的单调递增数字,并且不容易猜测过去或未来的签名会话值。尽管 express-session 使用 24 byte uid 作为其会话 ID,但在对其进行签名时,该值会扩展很多很多,这使得猜测和找到有效会话变得更加困难(我查看的签名 cookie 值是80 字节长(经过一些编码后)。

仅供参考,这里是对“为什么要签署 cookie?”的简化讨论:https://github.com/expressjs/session/issues/68 来自 express-session github 存储库。