给定cookie值的x
1
. .
Set-Cookie: x=1
. .a消息认证码(MAC)添加y
,在本例中使用|
分隔符。
Set-Cookie: x=1|y
数据1
和MACy
应该如何分开?上面使用了分隔符,但如果数据可能包含分隔符,则此方法将失败。我考虑使用JSON,
{ "data": 1, "mac": "y" }
我相信这将必须是url编码?
Set-Cookie: x=%7B%22x%22%3A1%2C%22mac%22%3A%22y%22%7D
是否有标准查询包含mac的cookie值的格式?
MACy
的计算应该与这个问题无关。如果有必要,请假设y
是使用OpenSSL HMAC SHA-256计算的。
如果我们从cookie的HTTP标准开始,我们会发现该语法没有对消息签名的任何特殊支持。所支持的是使用extension-av
语法通过属性实现的任意元数据。你可以这样写:
Set-Cookie: x=1;myhmac=y
或者,如本文所使用的,简称为x=1;y
。在实践中,这可能工作得很好,但在理论上,它遇到了与其他元数据使用冲突的问题(如果客户端对myhmac
应用其他含义怎么办?)。对于任何扩展标准的系统来说,这都是一个常见的问题。
如果HMAC不是http级别的元数据,那么它必须存储在cookie的内容中。您建议使用包含值和签名的数据结构,然后对其进行编码,这与标准一致:
为了最大限度地与用户代理、服务器兼容将任意数据存储在cookie值中,应该对该数据进行编码例如,使用Base64。
Base64当然比URL编码更可取,因为它有一个受限制的字符集,您可以简单地对值本身进行Base64,然后确保您选择的分隔符(假设.
)不会与值冲突。因此,不需要编码JSON对象,只需要:
Set-Cookie: x=Base64(1).Base64(y)
根据我的经验,这可能是最常见的方法:使用Base64作为值和签名,用您选择的分隔符分隔。举一个我熟悉的例子,Django是这样处理消息签名的,包括在cookie中,使用:
作为分隔符。
一个更通用的方法是使用JSON Web签名(JSON Web令牌的一部分),这是一个用于处理可用于标头的签名的拟议标准。这种方法类似于最后一种方法,但包含元数据(如所使用的算法)。紧凑语法是:
JWT库可能在所有语言中都可用。但是请注意,jwt的通用性和复杂性会带来潜在的安全风险,许多jwt会警告您不要这样做。BASE64URL(UTF8(JWS Protected Header)) || '。"| |BASE64URL(JWS有效载荷)|| '。"| |BASE64URL (jw签名)