CSRF令牌通常不会加密.在一个用于在普通Web应用程序中安装同步器令牌模式的教科书实现中,CSRF令牌只是一个足够大的随机值,存储在服务器上,也在表单生成时提供给客户端.然后,客户端可以将其与表单一起发回,以证明它发送的表单实际上是由服务器生成的,而不是其他人.(即使在双重发布等其他模式的情况下,作为标头字段和Cookie发送的令牌在基本情况下也只是一个随机令牌.)
然而,有两件事需要注意.
同步器令牌模式(classic 的CSRF令牌)需要服务器查找.如果有用户会话,这并不是什么大问题,但情况并不总是如此,一些应用程序被设计为无状态的.在这种情况下,您不能只拥有一个随机令牌,因为您无法在不判断服务器端状态的情况下决定它是否有效.
另一件需要注意的事情是,如果令牌包含一些关于客户端的信息,您实际上可以进一步提高安全性.例如,如果CSRF令牌以某种方式与客户端绑定(例如,如果它在更简单的实现中与当前客户端IP地址相关联),那么以某种方式窃取CSRF令牌就没那么有用了.同样,您可以将此附加信息存储在服务器端,但这也是一些应用程序希望避免的,以使负载平衡等事情更容易.
因此,它归结为无状态CSRF令牌,您只需按原样进行判断,而无需在后端进行状态(数据库)查找.
您可以做的(以及一些框架为您所做的)是,它们创建一个 struct 化令牌,其中嵌入了一些数据,并使用只有服务器知道的密钥对其进行加密.然后,服务器将其作为CSRF令牌发送,并期望在状态更改请求时将其接收回来.当它收到它时,服务器不需要数据库查找,它只需解密令牌,并查看它是否是服务器创建的有效令牌.
请注意,纯粹出于这个目的,您实际上不需要加密,更适合的加密原语将是消息验证码,因为您只关心令牌的真实性,即.是服务器自己创建的,而不是其他人.然而,某些框架包含在令牌中的数据通过加密(以及通过适当的经过身份验证的加密算法进行隐式消息身份验证)进一步得到多次保护.但在一个非常基本的实现中,您实际上可以只将时间戳和用户ID与HMAC一起作为无状态的CSRF令牌(但包括更多信息,甚至可能是关于所生成的表单字段的信息将进一步提高安全性).
因此,简而言之,未加密的随机令牌被认为足以用于CSRF,在双重发布的情况下,它们也可以是无状态的(由于同源策略,攻击者不能将相同的随机令牌作为Cookie和报头发布到不同的来源).但如果需要,加密的、信息更丰富的令牌可以提供更多的安全性,甚至可能在一定程度上减轻被盗的CSRF令牌威胁.