会话与基于令牌的身份验证 [英] Sessions vs. Token based authentication

查看:73
本文介绍了会话与基于令牌的身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道哪种认证更安全,为什么? 基于会话的身份验证还是基于令牌的身份验证?

I want to know which is more safe to implement for authentication and why? Session based authentication OR Token based authentication?

我知道会话也可以用于其他用途,但是现在我只对身份验证感兴趣.

I know sessions can be used for other things as well, but right now I am only interested about authentication.

如果使用令牌(服务器甚至不在内存中),则服务器端没有存储任何内容是真的吗?如果是,那么它如何针对过期的令牌进行标识,因为这些令牌也已使用相同的秘密进行了签名?

Is it true that nothing is stored on server side if using tokens (not even in memory)? If yes, then how it identifies against expired tokens as that had also been signed using the same secret?

推荐答案

上面评论中链接的有关信息安全的问题有很多相关信息.话虽如此,在这个问题上提出的一些其他问题也应该解决:

The question on Information Security linked in the comment above has a lot of relevant information. That being said, a few additional concerns raised in this question should be addressed:

对于服务器实现一无所知,这两种方法都是一样安全的.基于会话的身份验证主要取决于会话标识符的可猜测性(如信息安全性答案中所述,会话标识符本身就是一个非常简单的令牌).如果会话标识符是单调递增的数字id,则它不是很安全,OTOH可能是不透明的,具有强大密钥空间的加密强唯一ID,因此非常安全.您可能将使用所选服务器框架提供的会话实现,因此需要进行检查.之后,使用会话身份验证,您的服务器实现需要验证服务器存储的会话是否包含相关授权(即用户帐户数据,角色等),因为许多服务器会话框架将默认根据需要自动生成空会话,则不能以存在会话这一事实为依据来进行有效的身份验证和授权.

Knowing nothing about the server implementation, both methods can be as secure. Session-based authentication mostly relies on the guessability of the session identifier (which, as described in the Information Security answer, it in itself a very simple token). If the session identifier is a monotonously incrementing numeric id, then it is not very secure, OTOH it could be an opaque cryptographically strong unique ID with a huge keyspace, making it very safe. You are probably going to use the session implementation offered by your server framework of choice, so you need to check that. After that, using session authentication, your server implementation needs to verify that the server stored session contains the relevant authorization (i.e. user account data, role, etc) - as a lot of server session frameworks will be default auto-generate empty sessions as needed, the fact that a session exists must not be relied upon as proof enough for a valid authentication and authorization.

例如,PHP的内部会话ID生成使用完全随机的288位数字(默认设置),因此被认为是安全的OTOH-默认情况下,它会自动生成会话,因此必须遵守先前的注释(或禁用自动会话创建并确保服务器仅根据需要创建会话.)

For example, PHP's internal session ID generation uses a completely random 288 bits number (default setting) so it is considered safe, OTOH - by default it generates sessions automatically so the previous comment must be adhered to (or to disable automatic session creation and make sure the server only creates session as needed).

此外,如果使用HTTP URL查询字符串传递会话ID(这是过去几天的默认设置),则会话很容易被盗,从而使整个过程不安全.

Also, if the session ID is passed using an HTTP URL query string, as was the default in days of old, then the session can be stolen quite easily and that makes the whole process insecure.

令牌安全主要基于安全令牌生成:如果服务器以安全方式(即不可猜测和可验证)生成令牌,如信息安全性答案所示.一个天真的实现(我见过一次)可能是对MD5哈希一个已知的令牌,例如用户名,这使它非常不安全,即使加盐也是如此.使用加密令牌时,安全性与加密强度密切相关,加密强度取决于所使用的算法,密钥的长度以及(最重要的是)服务器密钥的保护程度:如果服务器密钥被硬编码到服务器中服务器实现,然后将这些代码开源...

Token safety is mostly based around secure token generation: if the server generates tokens in a secure manner - i.e. non-guessable and verifiable - as demonstrated in the Information Security answer. A naive implementation (that I saw one time) might be to MD5 hash a known token, such as a user name, and that makes it very unsafe, even when salted. When using cryptographic tokens, safety is closely related to the strength of encryption which is determined by the algorithm used, length of the key, and - most importantly - how well the server key is secured: if the server key is hard-coded into the server implementation and that code is then open-sourced...

服务器是否需要存储任何内容通常取决于令牌的实现.

Whether the server needs to store anything generally depends on the implementation of the tokens.

许多实现将"API密钥"的概念用作令牌身份验证",因此令牌通常只是数据库的某种加密安全ID,该ID记录了已生成的"API密钥".这需要存储,但是具有实现更简单的优势,并且更重要的是具有撤消令牌的能力.

A lot of implementations use the concept of an "API key" as "token authentication" and so often tokens are just some cryptographically secure ID to a database that records which "API keys" have been generated. This requires storage but has the advantage of a simpler implementation and - more importantly - the ability to revoke tokens.

另一种方法是让令牌具有自己的真实性-这允许服务器从本质上将令牌的存储卸载到客户端,并将客户端用作数据库-非常像HTTP Cookies允许服务器卸载某些存储的方式对客户端的要求(通常用于客户端的特定设置,例如用户是想要浅界面还是暗界面).

The other approach is to have the token carry its own authenticity - this allows the server to essentially offload the storage of tokens to the client and use the client as the database - very much like how HTTP Cookies allow servers to offload some storage requirements to the client (often used for client's specific settings, like whether the user wants a light interface or a dark interface).

信息安全性答案中很好地演示了用于此目的的两种模式:签名和加密.

The two patterns used for this are demonstrated well in the Information Security answer: signing and encrypting.

  • 签名:令牌是身份验证者凭据(例如用户名)的某种简单编码(例如JSON或CSV),并且可能是令牌的到期时间(如果您希望令牌过期,通常是个好主意, (如果无法撤消令牌),则服务器使用服务器密钥对生成的文本进行签名,并将其添加到令牌中.当客户端提交令牌时,服务器可以从令牌中提取明文,对其进行重新签名,然后将新签名与提交的令牌中的签名部分进行比较-如果它们相同,则该令牌有效.这里的主要缺点是,应注意明文身份验证详细信息严重不足以使攻击者重新进行身份验证-否则会损害安全性要求.即不要将密码作为令牌的一部分发送.

  • Signing: The token is some simple encoding (like JSON or CSV) of the authenticator credentials (such as the username) and possibly the token's expiry time (if you want to have tokens expire - generally a good idea, if you can't revoke tokens), and then the server signs the generated text using a server secret and adds that to the token. When the client submits the token, the server can extract the clear text from the token, re-sign it and compare the new signature to the signature part in the submitted token - if they are identical, then the token is valid. The main disadvantage here that care should be taken that the clear-text authentication details are strongly insufficient for an attacker to re-authenticate - otherwise, it harms the safety requirement. i.e. don't send the password as part of the token.

加密:通过再次编码所有相关的身份验证详细信息,然后使用服务器机密加密明文并仅提交加密结果,来生成令牌.

Encrypting: the token is generated by again encoding all the relevant authentication details and then encrypting the clear-text with a server secret and only submitting the encrypted result.

在这两种方法中,安全性都与加密/签名算法的强度密切相关-一种弱算法将使攻击者可以对服务器机密进行逆向工程,并无需身份验证即可生成新的有效令牌.

In both methods, safety is closely related to the strength of the encryption/signing algorithm - a weak algorithm will allow an attacker to reverse engineer the server secret and generate new valid tokens without authentication.

我认为,基于密码令牌的身份验证往往不如基于会话的安全,因为它依赖(通常是单个)开发人员完成从设计到实现再到部署的一切工作,而基于会话的身份验证可以利用现有的身份验证.实现最繁重的工作,在这里很容易找到高质量,安全且被大量使用和测试的会话存储实现.在建议使用加密令牌之前,我需要一个非常有说服力的理由来说明为什么不需要会话存储.

In my opinion, cryptographic token-based authentication tends to be less safe than session-based, as it relies on the (often single) developer doing everything right from design to implementation to deployment, while session-based authentication can leverage existing implementations to do most of the heavy lifting, where it is very easy to find high-quality, secure and massively used and tested session storage implementations. I would need a very compelling reason as to why session storage is unwanted before recommending using cryptographic tokens.

永远记住加密安全的第一规则:永远不要设计自己的一次性加密措施.

Always remember the no.1 rule of cryptographic security: never design your own single-use cryptographic measures.

这篇关于会话与基于令牌的身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆