给定一个 cookie x
和一个 value 1
..
Set-Cookie: x=1
.. 添加了一个消息验证码 (MAC) y
,在本例中带有一个|
分隔符。
Set-Cookie: x=1|y
数据 1
和 MAC y
应该如何分开?上面使用了分隔符,但如果数据可能包含分隔符,则此方法将失败。我考虑过使用 JSON,
{ "data": 1, "mac": "y" }
我认为这必须进行 URL 编码?
Set-Cookie: x=%7B%22x%22%3A1%2C%22mac%22%3A%22y%22%7D
对于包含 MAC 的 cookie 值的格式是否有标准?
MAC y
的计算应该与本题无关。如有必要,请假设 y
是使用 OpenSSL HMAC SHA-256 计算的.
最佳答案
如果我们从 cookie 的 HTTP 标准开始,我们会看到 syntax对消息签名没有任何特殊支持。 支持的是使用 extension-av
语法通过属性实现的任意元数据。所以你可以这样做:
Set-Cookie: x=1;myhmac=y
或者,如 this article 中所用,简单地 x=1;y
。在实践中这可能工作正常,但理论上它会遇到与其他元数据使用冲突的问题(如果客户端对 myhmac
应用其他含义怎么办?)。这是任何用于扩展标准的系统的常见问题。
如果 HMAC 不是 HTTP 级元数据,则它必须存储在 cookie 的内容中。您建议使用包含值和签名的数据结构然后对其进行编码符合标准:
To maximize compatibility with user agents, servers that wish to store arbitrary data in a cookie-value SHOULD encode that data, for example, using Base64.
Base64 肯定比 URL 编码更可取,因为它有一个受限的字符集,你可以简单地对值本身进行 Base64,然后确保你选择的分隔符(比如 .
)不会与值(value)发生冲突。因此,您可以简单地执行以下操作,而不是编码 JSON 对象:
Set-Cookie: x=Base64(1).Base64(y)
根据我的经验,这可能是最常见的方法:使用 Base64 作为值和签名,由您选择的分隔符分隔。举一个我熟悉的例子,这就是 Django 处理 message signing 的方式。 ,包括在 cookie 中,使用 :
作为分隔符。
更通用的方法是使用 JSON Web Signatures (JSON Web Tokens 的一部分),一个用于处理可在 header 中使用的签名的提议标准。这种方法类似于上一种方法,但包括元数据(如使用的算法)。简洁的语法是:
BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)
JWT 库可能以所有语言提供。但请注意,JWT 的通用性和复杂性会带来潜在的安全风险,许多人会 warn you away .
关于http - cookie 中的 HMAC 有标准格式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66067645/