gitbook/安全攻防技能30讲/docs/178520.md
2022-09-03 22:05:03 +08:00

116 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 04 | 身份认证:除了账号密码,我们还能怎么做身份认证?
你好,我是何为舟。
上一讲,我们详细讲解了密码学的三种算法:高效安全的对称加密算法,解决密钥分发难题的非对称加密算法,以及提供单向加密的散列算法。
在表达了你对密码学清晰的理解之后面试官开始相信你具备安全方面的基础知识了。于是他准备和你探讨一下安全落地的细节。基于你之前提出的“黄金法则”面试官问道“黄金法则的认证Authentication部分不就是账号密码吗这么简单的东西有必要考虑得那么复杂吗
认证,也就是身份识别与认证(通常来说,识别和认证是一体的,因此后面我会用身份认证来指代识别和认证)。毫无疑问,对于一个安全的应用来说,身份认证是第一道门槛,它为后续所有的安全措施提供“身份”这样一个关键信息。
听完你的简单叙述后,面试官直接问道:“现在我们公司有好几个应用,每一个应用都有独立的账号体系,管理起来十分复杂。而且,内部员工的账号体系也没有建设起来。如果是你,你会怎么解决这些问题呢?”
现在你可能很难回答这些问题,没关系,带着这些问题,让我们来学习今天的内容。相信学完之后,再有人问,你都可以对答如流。
## 身份认证包括哪些东西?
首先,身份认证不仅仅是一个输入账号密码的登录页面而已,应用的各个部分都需要涉及身份认证。在我看来,身份认证可以分为两个部分:**对外认证和对内认证**。
对外认证,其实就是应用的登录注册模块,它面向用户进行认证。对外认证的入口比较集中,一个应用通常只有一个登录入口。因此,我们可以在登录这个功能上,实现很多种认证的方式。这就可以用到我们之前提到的“你知道什么、你拥有什么、你是什么”。
除了应用本身需要有登录注册的模块应用的各种内部系统同样需要涉及登录认证的功能比如服务器的登录、数据库的登录、Git的登录、各种内部管理后台的登录等等。这也就是我所说的对内认证。
那么,对内认证和对外认证有什么区别呢?我觉得,它们最主要的区别在于认证场景的复杂程度。从下面这张图中我们可以看出,**对外认证是单一场景下的认证,对内认证是多场景下的认证**。
![](https://static001.geekbang.org/resource/image/1e/f6/1edb8214ddeb59bf93b85d008d4b0ff6.jpeg)
在了解了对内、对外认证的特点之后,我们再来聊一聊它们的应用。我了解到的目前行业的现状是,各个公司的对内认证都比较薄弱。其主要原因在于,内部的认证场景过于分散,很难进行统一管理。尤其是服务器、数据库等的认证,目前还无法做到统一。因此,对内认证是一个长期治理的过程,需要我们投入较大的精力。
正如我在[第一节课](https://time.geekbang.org/column/article/176567)中提到的,“面对一个问题时,我们总是很容易发现表面的影响,而忽视其产生的根本原因”,在身份认证这个问题上同样如此。表面上,我们要做好对外认证,防止用户的账号被盗。根本上或者说更普遍的问题是,我们要如何做好对内认证。因此,当你在考虑身份认证的安全问题时,一定要尽可能考虑得更全面。毕竟,对于安全来说,有一个小场景没做到位,很多时候,就意味着什么都没做。
## 身份认证主要面临哪些威胁?
接下来,你肯定想问,我们该如何做好身份认证呢?不要着急,我们先来看一下身份认证都会面临哪些威胁。只要我们针对这些威胁找到对应的解决办法,就能做好身份认证了。身份认证面临的威胁主要包括无认证、弱密码、认证信息泄露。接下来,我们一个一个来看。
首先,**没有认证环节**是所有应用和公司存在的最普遍的问题。尤其是在对内认证的部分,我们经常会看到,很多公司的数据库、接口、管理后台在使用的时候,并不需要经过认证这个环节。
除了没有认证环节的直接“裸奔”,**弱密码**也是一个普遍存在的问题。我常常觉得,安全最大的敌人是人类的惰性。设计一个好记的强密码并不是一件简单的事情,这也是弱密码屡禁不止的原因。
说完了无认证和弱密码,接下来我们来聊一聊**认证信息泄露**。所谓认证信息泄露,就是指黑客通过各种手段,拿到了用户的密码信息和身份凭证这样的认证信息。常见的手段包括钓鱼、拖库等等。更可怕的是,很多攻击对于用户来说都是无感知的。
那么,无感知体现在哪里呢?我们可以来做一个小测试。你可以在[haveibeenpwned](https://haveibeenpwned.com)中输入自己的账号信息测试一下它们是否被泄露了。如果显示“Oh no -powned!”,那就说明你的邮箱密码已经被泄露了,我建议你可以尽快修改你的密码了。
![](https://static001.geekbang.org/resource/image/3e/44/3e1b75ff1a291332e17b9d311c708d44.png)
除了密码的直接泄露以外大部分的登录系统都无法应对重放攻击。重放攻击简单来说就是黑客在窃取到身份凭证如Cookie、Session ID之后就可以在无密码的情况下完成认证了。
总结来说,**身份认证面临的威胁其实都是认证信息的泄露**。这其中,既可能是应用本身就没有认证信息或者认证信息强度比较弱,使得黑客可以通过猜测的方式快速获取认证信息;也有可能是黑客通过一些攻击手段(如窃听等),从用户那获取了认证信息,从而冒充用户进行登录。
而身份认证被破解的后果,相信你也知道一些:一旦黑客仿冒了正常用户进行认证,那么就相当于获得了这个用户的所有权限。更严重的是,所有的后续操作,都会记录到这个正常用户的名下,使得后续应用进行授权和审计的时候,都很难发现黑客本身的存在。
## 身份认证的安全怎么保证?
在了解了身份认证环节会面临的各种威胁,以及这些威胁可能产生的影响之后,你可能要问了,我们应该怎么解除这些威胁呢?我觉得,很多时候,我们解决安全问题,**不只是在解决一个技术问题,还要培养外部用户和内部员工的安全意识**。也就是说,认证安全并没有什么完善的技术解决方案,更多的是通过一些规章制度去强化我们的安全意识。
尽管如此,我这里也会去讲一些技术方案,让你知道一些基本的解决方案。
比如,对密码的强度进行限制(如强制使用字母、数字、特殊字符的组合密码,并达到一定长度),强制用户定期修改密码,对关键操作设置第二密码(如微信、支付宝的支付密码)等等。
当然,随着互联网的发展,我们也会不断地利用新技术去升级验证手段,帮助用户降低被“攻击”的风险。比如,通过手机验证替代密码验证(因为丢失手机的几率比丢失密码的几率低);通过人脸、指纹等生物特征替代密码。
除此之外我们还可以通过加密信道如HTTPS来防止窃听也可以通过给下发的凭证设置一个有效期来限制凭证在外暴露的时间以此来减少重放攻击带来的影响。
这里面有一点你要注意,身份认证的最大的问题还是在于身份管理。随着公司业务的不断扩张,当账号体系变得越来越复杂时,如何对这些账号进行统一的管理,是解决身份认证问题的关键。而**单点登录**就是一个非常有效的解决方案。
## 单点登录如何解决身份认证问题?
那么**单点登录**Single Sign OnSSO到底是什么呢单点登录的概念很简单用户只需要进行一次认证就可以访问所有的网页、应用和其他产品了。随着互联网产品形式的不断发展单点登录的实现方式也经历了多次的升级革新。下面我为你介绍几种典型的单点登录方式它们分别是**CAS流程、JWT、OAuth和OpenID**。
第一个要讲的是**CAS**Central Authentication Service集中式认证服务**流程**。
CAS是一个开源的单点登录框架它不属于某一种单点登录的实现方式而是提供了一整套完整的落地方案。整体的流程如下图所示具体步骤我会通过访问极客时间App的例子来为你详细讲解。
![](https://static001.geekbang.org/resource/image/5f/e0/5f5b3dfe3d9203a4c413a73aab43c2e0.jpeg)
1. 假如用户现在要访问某个应用比如极客时间App。
2. 应用需要进行认证但应用本身不具备认证功能。因此应用将用户重定向至认证中心的页面。比如你在登录一个应用的时候它显示你可以选择微信、QQ、微博账号进行登录你点击微信登录就跳转至微信的登录页面了。
3. 用户在认证中心页面进行认证操作。如果用户之前已经在其他应用进行过认证了,那么认证中心可以直接识别用户身份,免去用户再次认证的过程。
4. 认证完成后认证中心将认证的凭据有时会加上用户的一些信息一起返回给客户端。也就是你在微信登录完成后回到了极客时间App。
5. 客户端将凭据和其他信息发送给应用也就是说极客时间App将微信的登录凭据发送给了极客时间后端。
6. 应用收到凭据后,可以通过签名的方式,验证凭据的有效性。或者,应用也可以直接和认证中心通信,验证凭据并获取用户信息。这也就是为什么极客时间能够拿到你的微信头像了。
7. 用户完成认证。
CAS的流程非常经典你现在应该理解了吧我们后面要讲的3种单点登录方式都和CAS的流程相似说它们是CAS的“衍生品”也不为过。所以说你一定要先掌握了CAS流程然后再来看下面这3种。
**JWT**JSON Web Token是一种非常轻量级的单点登录流程。它会在客户端保存一个凭证信息之后在你每一次登录的请求中都带上这个凭证将其作为登录状态的依据。**JWT的好处在于不需要应用服务端去额外维护Cookie或者Session了**。但是,正是因为它将登录状态落到了客户端,所以我们无法进行注销等操作了。
**OAuth**Open Authorization的主要特点是授权也是我们通常用QQ、微信登录其他应用时所采用的协议。通过OAuth用户在完成了认证中心的登录之后应用只能够验证用户确实在第三方登录了。但是想要维持应用内的登录状态应用还是得颁发自己的登录凭证。这也就是为什么QQ授权后应用还需要绑定你的手机号码。这也就意味着应用是基于QQ的信息创建了一个自身的账号。
![](https://static001.geekbang.org/resource/image/3d/35/3dbf85c7efa778af6cada3dd0b47ca35.png)
**OpenID**Open Identity Document和OAuth的功能基本一致。但是OpenID不提供授权的功能。最常见的当我们需要在应用中使用微信支付的时候应用只需要收集支付相关的信息即可并不需要获取用户的微信头像。
在实际情况中基于各种业务需求的考虑很多公司都倾向于自己去实现一套SSO的认证体系它的认证流程如下图所示
![](https://static001.geekbang.org/resource/image/b2/66/b2d9580b67730906b26665c92fcc8666.jpeg)
在这个流程中,应用的服务器直接接收用户的认证信息,并转发给认证中心。对用户来说,这个认证中心是完全透明的。但是,这个流程给予了应用过多的信任,从安全性方面考量的话,是不合理的。在这个过程中,应用直接获取到了用户的认证信息,但应用能否保护好这些信息呢?我们并没有有效的办法去做确认。
因此我的建议是多花一些功夫去接入成熟的单点登录体系而不是自己去实现一个简化版的。JWT适用范围广在单点登录的选取上面如果想要将用户信息做统一管理选择它最为简单如果认证中心只是被用来维护账号密码由业务去维护用户所绑定的其他手机等信息那么采用OAuth更合适。
## 总结
好了,今天的内容差不多了,下面我来带你总结回顾一下,你要掌握的重点内容。
身份认证的主要场景可以分为对外认证和对内认证。其中对内认证往往会因为管理的疏忽导致很严重的问题。从威胁上来说无认证和弱密码是最普遍的安全问题。除此之外各种密码和认证信息的窃取也是黑客常用的攻击手段。对于身份认证来说单点登录是一种集大成的解决方案。基于CAS流程衍生出了很多成熟的单点登录流程可以供你去使用。
那么,掌握身份认证的一些技巧,对我们有哪些帮助呢?首先,任何的应用都会存在对内和对外的认证,因此,这将是你提升应用安全水平的一个首要任务。其次,在复杂的应用系统和网络结构中,如何管理身份认证,既优化用户体验,又保证其安全性,对你的设计和管理能力都是一个考验。做好了身份认证,不论是在安全上,还是在个人能力上,你都能够得到极大的提升。
## 思考题
好了,学习了今天的内容,你现在可以来思考一下面试官的问题:怎么做好认证?
这里我先给你提供一个思路。首先,你需要告诉面试官,公司目前存在哪些认证问题。这些认证问题的存在,可能导致哪些严重后果。接下来,就可以设想一下,想要解决这些认证问题,你会设计出怎样的认证体系。
欢迎留言和我分享你的思考和疑惑,也欢迎你把文章分享给你的朋友。我们下一讲再见!