我想知道哪种方法可以更安全地进行身份验证?&为什么? 基于会话的身份验证或基于令牌的身份验证
我知道会话也可用于其他事情,但现在我只对身份验证感兴趣。
如果使用令牌(甚至在内存中),服务器端是否存在任何内容?如果是,那么它如何识别过期的令牌,因为它也是使用相同的秘密签署的?
答案 0 :(得分:28)
在基于会话的身份验证中,服务器完成所有繁重的服务器端。从广义上讲,客户端使用其凭据进行身份验证并接收session_id(可以存储在cookie中)并将其附加到每个后续传出请求。因此,这可以被视为“令牌”,因为它相当于一组凭证。
然而,这个session_id-String没什么特别之处。它只是一个标识符,服务器完成其他所有操作。这是有状态的。它将标识符与用户帐户相关联(例如,在存储器中或在数据库中)。它可以将此会话限制或限制为某些操作或特定时间段,并且如果存在安全问题则可以使其无效,更重要的是,它可以动态执行并更改所有这些操作。
此外,它可以记录用户在网站上的每一个动作。可能的缺点是可扩展性差(特别是在多个服务器场上)和大量内存使用。
在基于令牌的身份验证中,没有会话在服务器端(无状态)持久化。最初的步骤是一样的。凭证与令牌交换,然后附加到每个后续请求(它也可以存储在cookie中)。
然而,为了减少内存使用,简单的扩展能力和总灵活性(令牌可以与另一个客户端交换),发出一个包含所有必要信息的字符串(令牌),在每次请求之后检查该字符串。客户端到服务器。
有许多方法可以使用/创建令牌:
使用散列机制,例如HMAC-SHA1
token = user_id|expiry_date|HMAC(user_id|expiry_date, k)
- id和expiry_id以明文形式发送,附加结果哈希(k只知道服务器)
对称地加密令牌,例如使用AES
token = AES(user_id|expiry_date, x)
- x表示加密/解密密钥
非对称加密,例如与RSA
token = RSA(user_id|expiry_date, private key)
生产系统通常比这两种原型更复杂。例如亚马逊在其网站上使用这两种机制。此外,混合物可以用于发布令牌,如2中所述,并且还将用户会话与其关联以用于用户跟踪或可能的撤销,并且仍然保持经典令牌的客户端灵活性。此外,OAuth 2.0使用短期和特定的承载令牌和更长寿命的刷新令牌,例如获得持票人代币。
<强>来源:强>
答案 1 :(得分:4)
上面评论中链接的有关信息安全的问题有很多相关信息。话虽如此,在这个问题上提出的一些其他问题也应该解决:
对于服务器实现一无所知,这两种方法都一样安全。基于会话的身份验证主要依赖于会话标识符的可猜测性(如信息安全性答案中所述,会话标识符本身就是一个非常简单的令牌)。如果会话标识符是单调递增的数字ID,那么它不是很安全,OTOH可能是不透明的,具有强大密钥空间的加密强唯一ID,因此非常安全。您可能将使用所选服务器框架提供的会话实现,因此需要进行检查。之后,使用会话身份验证,您的服务器实现需要验证服务器存储的会话是否包含相关授权(即用户帐户数据,角色等),因为许多服务器会话框架将默认根据需要自动生成空会话,则不能以存在会话这一事实为依据来进行有效的身份验证和授权。
例如,PHP的内部会话ID生成使用完全随机的288位数字(默认设置),因此被认为是安全的OTOH-默认情况下,它会自动生成会话,因此必须遵守先前的注释(或禁用自动会话创建并确保服务器仅根据需要创建会话。)
此外,如果使用HTTP URL查询字符串传递会话ID(这是过去几天的默认设置),则会话很容易被盗,从而使整个过程不安全。
令牌安全主要基于安全令牌生成:如果服务器以安全方式(即不可猜测和可验证)生成令牌,如信息安全性答案所示。一个天真的实现(我见过一次)可能是对MD5哈希一个已知的令牌,例如用户名,这使它非常不安全,即使加盐也是如此。使用加密令牌时,安全性与加密强度密切相关,加密强度取决于所使用的算法,密钥的长度以及(最重要的是)服务器密钥的保护程度:如果服务器密钥被硬编码到服务器中服务器实现,然后将代码开源...
服务器是否需要存储任何内容通常取决于令牌的实现。
许多实现将“ API密钥”的概念用作“令牌身份验证”,因此令牌通常只是数据库的某种加密安全ID,该ID记录了已生成的“ API密钥”。这需要存储,但是具有实现更简单的优势,并且更重要的是具有撤消令牌的能力。
另一种方法是让令牌具有自己的真实性-这允许服务器从本质上将令牌的存储卸载到客户端,并将客户端用作数据库-非常类似于HTTP Cookies如何允许服务器卸载某些存储对客户端的要求(通常用于客户端的特定设置,例如用户是想要亮界面还是暗界面)。
信息安全性答案中很好地演示了用于此目的的两种模式:签名和加密。
签名:令牌是身份验证者凭据(例如用户名)的某种简单编码(例如JSON或CSV),并且可能是令牌的到期时间(如果您希望令牌过期-通常是一个好主意, (如果您无法撤消令牌),则服务器使用服务器密钥对生成的文本进行签名,并将其添加到令牌中。当客户端提交令牌时,服务器可以从令牌中提取明文,对其进行重新签名,然后将新签名与提交的令牌中的签名部分进行比较-如果它们相同,则该令牌有效。验证之后,您可能想要对照当前时间检查验证的到期日期。这里的主要缺点是,应注意明文身份验证详细信息严重不足以使攻击者重新进行身份验证-否则会损害安全性要求。也就是说,请勿将密码作为令牌或其他任何内部详细信息的一部分发送。
加密:通过再次编码所有相关的身份验证详细信息,然后使用服务器机密加密明文并仅提交加密结果,来生成令牌。如果可以信任加密方案,则身份验证详细信息可以包括内部数据-但应注意,对于攻击者而言,脱机可用的大型加密文本比小签名具有更大的攻击面,弱加密算法的弹性较小这种使用方式不只是签名。
在这两种方法中,安全性都与加密/签名算法的强度密切相关-一种弱算法将使攻击者可以对服务器机密进行反向工程,并在不进行身份验证的情况下生成新的有效令牌。
我认为,基于密码令牌的身份验证往往不如基于会话的安全,因为它依赖于(通常是单个)开发人员完成从设计到实现再到部署的一切工作,而基于会话的身份验证可以利用现有的实现最繁重的工作,在这里很容易找到高质量,安全且被大量使用和测试的会话存储实现。在建议使用加密令牌之前,我需要一个非常有说服力的理由来说明为什么不需要会话存储。
永远记住加密安全的第一规则:永远不要设计自己的一次性加密措施。
答案 2 :(得分:3)
在回答您的问题之前,让我先介绍一下使用基于令牌的身份验证和基于会话的身份验证的利弊:
基于会话的身份验证
优点:
缺点:
令牌认证
专业人士
缺点
第一个问题:
哪个更安全实施?
答案:会话身份验证
原因:
1.无论哪种方式,您仍然需要维护服务器状态
2.您的数据总是比客户端更安全的服务器端
3.与XSS相比,缓解CSRF攻击非常容易或更容易
4.会话易于管理
5.数据永不过时
第二个问题
答案:除了已撤消的令牌外,用户会话不会保存在服务器端