04-⾝份认证: 除了账号密码 ,我们还能怎么做⾝份认证?
上⼀讲 ,我们详细讲解了密码学的三种算法:⾼效安全的对称加密算法 ,解决密钥分发难题的⾮对称加密算法 , 以及提供单向加密的散列算法。
在表达了你对密码学清晰的理解之后 ,⾯试官开始相信你具备安全⽅⾯的基础知识了。于是 ,他准备和你探讨⼀ 下安全落地的细节。基于你之前提出的“⻩⾦法则” ,⾯试官问道:“⻩⾦法则的认证(Authentication) 部分不就是账号密码吗?这么简单的东西 ,有必要考虑得那么复杂吗?”
认证 ,也就是⾝份识别与认证 (通常来说 ,识别和认证是⼀体的 ,因此后⾯我会⽤⾝份认证来指代识别和认证) 。毫⽆疑问 ,对于⼀个安全的应⽤来说 ,⾝份认证是第⼀ 道⻔槛 ,它为后续所有的安全措施提供“⾝ 份”这样 一个关键信息。听完你的简单叙述后 ,⾯试官直接问道:“现在我们公司有好⼏个应⽤ ,每⼀个应⽤都有独⽴的账号体系,管理起来⼗分复杂。⽽且 , 内部员⼯的账号体系也没有建设起来。如果是你 ,你会怎么解决这些问题呢?”
现在你可能很难回答这些问题 ,没关系 ,带着这些问题 ,让我们来学习今天的内容。相信学完之后 ,再有⼈问 ,你都可以对答如流。
⾝份认证包括哪些东西?⾸先 ,⾝份认证不仅仅是⼀ 个输⼊账号密码的登录⻚⾯⽽已 ,应⽤的各个部分都需要涉及⾝份认证。在我看来 ,⾝份认证可以分为两个部分:对外认证和对内认证。
对外认证 ,其实就是应⽤的登录注册模块 ,它⾯向⽤⼾进⾏认证。对外认证的⼊⼝⽐较集中 ,⼀ 个应⽤通常 只有⼀ 个登录⼊⼝ 。因此 ,我们可以在登录这个功能上 ,实现很多种认证的⽅式。这就可以⽤到我们之前提
到的“你知道什么、你拥有什么、你是什么”。
除了应⽤本⾝需要有登录注册的模块 ,应⽤的各种内部系统同样需要涉及登录认证的功能 ,⽐如:服务器的 登录、数据库的登录、Git的登录、各种内部管理后台的登录等等。这也就是我所说的对内认证。
那么 ,对内认证和对外认证有什么区别呢? 我觉得 , 它们最主要的区别在于认证场景的复杂程度。 从下⾯这张图中我们可以看出 ,对外认证是单⼀场景下的认证 ,对内认证是多场景下的认证。⽬前还⽆法做到统⼀ 。因此 ,对内认证是⼀ 个⻓期治理的过程 ,需要我们投⼊较⼤的精力。
在了解了对内、对外认证的特点之后 ,我们再来聊⼀ 聊它们的应⽤ 。我了解到的⽬前⾏业的现状是 ,各个公
司的对内认证都⽐较薄弱。其主要原因在于 , 内部的认证场景过于分散 ,很难进⾏统⼀ 管理。尤其是服务精⼒。
正如我在第⼀节课中提到的 ,“⾯对一个问题时 ,我们总是很容易发现表⾯的影响 ,⽽忽视其产⽣的根本原因” , 在⾝份认证这个问题上同样如此。 表⾯上 , 我们要做好对外认证 , 防⽌用户的账号被盗。 根本上或者说更普遍的问题是 ,我们要如何做好对内认证。 因此 , 当你在考虑⾝份认证的安全问题时 ,⼀ 定要尽可能考虑得更全⾯ 。毕竟 ,对于安全来说 ,有⼀ 个⼩场景没做到位 ,很多时候 ,就意味着什么都没做。
⾝份认证主要⾯临哪些威胁?接下来 ,你肯定想问 ,我们该如何做好⾝份认证呢? 不要着急 ,我们先来看⼀ 下⾝份认证都会⾯临哪些威胁。 只要我们针对这些威胁找到对应的解决办法 , 就能做好⾝份认证了。 ⾝份认证⾯临的威胁主要包括⽆认证、弱密码、 认证信息泄漏。 接下来 ,我们⼀ 个⼀ 个来看。
⾸先 ,没有认证环节是所有应⽤和公司存在的最普遍的问题。尤其是在对内认证的部分 ,我们经常会看到, 很多公司的数据库、接⼝ 、管理后台在使⽤的时候 ,并不需要经过认证这个环节。除了没有认证环节的直接“裸奔” ,弱密码也是⼀ 个普遍存在的问题。我常常觉得 ,安全最⼤的敌⼈是⼈类的惰性。设计⼀ 个好记的强密码并不是⼀ 件简单的事情 ,这也是弱密码屡禁不⽌的原因。说完了⽆认证和弱密码 ,接下来我们来聊⼀ 聊认证信息泄漏。 所谓认证信息泄露 ,就是指⿊客通过各种⼿段 ,拿到了⽤⼾的密码信息和⾝份凭证这样的认证信息。 常⻅的⼿段包括钓⻥ 、拖库等等。 更可怕的是 ,很 多攻击对于用户来说都是⽆感知的。
那么 ,⽆感知体现在哪⾥呢?你都不知道你的密码已经被泄露了。
除了密码的直接泄漏以外 ,⼤部分的登录系统都⽆法应对重放攻击。重放攻击简单来说就是 ,⿊客在窃取到 ⾝份凭证 (如Cookie、Session ID) 之后 ,就可以在⽆密码的情况下完成认证了。
总结来说 ,⾝份认证⾯临的威胁其实都是认证信息的泄漏。 这其中 , 既可能是应⽤本⾝就没有认证信息或者认证信息强度⽐较弱 ,使得⿊客可以通过猜测的⽅式快速获取认证信息; 也有可能是⿊客通过⼀ 些攻击⼿段(如窃听等) , 从用户那获取了认证信息 , 从⽽冒充用户进⾏登录。⽽⾝份认证被破解的后果 ,相信你也知道⼀ 些: ⼀ 旦⿊客仿冒了正常用户进⾏认证 ,那么就相当于获得了这个用户的所有权限。 更严重的是 ,所有的后续操作 ,都会记录到这个正常⽤⼾的名下 ,使得后续应⽤进⾏授 权和审计的时候 ,都很难发现⿊客本⾝的存在。
⾝份认证的安全怎么保证?在了解了⾝份认证环节会⾯临的各种威胁 , 以及这些威胁可能产⽣的影响之后 ,你可能要问了 ,我们应该怎么解除这些威胁呢? 我觉得 ,很多时候 , 我们解决安全问题 ,不只是在解决⼀个技术问题 ,还要培养外部⽤⼾和内部员⼯的安全意识。 也就是说 , 认证安全并没有什么完善的技术解决⽅案 , 更多的是通过⼀ 些规章制度去强化我们的安全意识。
尽管如此 ,我这⾥也会去讲⼀ 些技术⽅案 ,让你知道⼀ 些基本的解决⽅案。
⽐如 ,对密码的强度进⾏限制 (如强制使⽤字⺟ 、数字、 特殊字符的组合密码 ,并达到⼀ 定⻓度) ,强制⽤⼾定期修改密码 , 对关键操作设置第⼆密码 (如微信、 ⽀付宝的⽀付密码) 等等。
当然 ,随着互联⽹的发展 ,我们也会不断地利⽤新技术去升级验证⼿段 ,帮助⽤⼾降低被“攻击”的⻛险。 ⽐如 ,通过⼿机验证替代密码验证 (因为丢失⼿机的⼏率⽐丢失密码的⼏率低) ;通过⼈脸、指纹等⽣物特 征替代密码。除此之外 ,我们还可以通过加密信道 (如HTTPS) 来防⽌窃听; 也可以通过给下发的凭证设置⼀ 个有效期 , 来限制凭证在外暴露的时间 , 以此来减少重放攻击带来的影响。
这⾥⾯有⼀ 点你要注意 ,⾝份认证的最⼤的问题还是在于⾝份管理。 随着公司业务的不断扩张 , 当账号体系变得越来越复杂时 ,如何对这些账号进⾏统⼀ 的管理 ,是解决⾝份认证问题的关键。⽽ 单点登录就是⼀ 个⾮常有效的解决⽅案。
单点登录如何解决⾝份认证问题?那么单点登录 (Single Sign On ,SSO) 到底是什么呢? 单点登录的概念很简单: ⽤⼾只需要进⾏⼀ 次认证 ,就可以访问所有的⽹⻚ 、应⽤和其他产品了。 随着互联⽹产品形式的不断发展 ,单点登录的实现⽅式也 经历了多次的升级⾰新。 下⾯我为你介绍⼏种典型的单点登录⽅式 , 它们分别是: CAS流程、JWT、 OAuth和OpenID。
第⼀ 个要讲的是CAS (Central Authentication Service ,集中式认证服务) 流程。
CAS是⼀ 个开源的单点登录框架 , 它不属于某⼀种单点登录的实现⽅式 ,⽽是提供了⼀ 整套完整的落地⽅
案。 整体的流程如下图所⽰ , 具体步骤我会通过访问极客时间App的例⼦来为你详细讲解。
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的信息创建了⼀ 个⾃⾝的账号。
OpenID (Open Identity Document) 和OAuth的功能基本⼀ 致。但是 ,OpenID不提供授权的功能。 最常⻅的 , 当我们需要在应⽤中使⽤微信⽀付的时候 ,应⽤只需要收集⽀付相关的信息即可 ,并不需要获取⽤⼾ 的微信头像。
在实际情况中 ,基于各种业务需求的考虑 ,很多公司都倾向于⾃⼰去实现⼀ 套SSO的认证体系 , 它的认证流程如下图所⽰:
在这个流程中 ,应⽤的服务器直接接收⽤⼾的认证信息 ,并转发给认证中⼼。对⽤⼾来说 ,这个认证中⼼是 完全透明的。但是 ,这个流程给予了应⽤过多的信任 ,从安全性⽅⾯考量的话 ,是不合理的。在这个过程 中 ,应⽤直接获取到了⽤⼾的认证信息 ,但应⽤能否保护好这些信息呢?我们并没有有效的办法去做确认。
因此 ,我的建议是 ,多花⼀些功夫去接⼊成熟的单点登录体系 ,⽽不是⾃⼰去实现⼀ 个简化版的。JWT适⽤范围⼴ ,在单点登录的选取上⾯ ,如果想要将⽤⼾信息做统⼀ 管理 ,选择它最为简单;如果认证中⼼只是被⽤来维护账号密码 , 由业务去维护⽤⼾所绑定的其他⼿机等信息 ,那么 ,采⽤OAuth更合适。
总结好了 ,今天的内容差不多了 ,下⾯我来带你总结回顾⼀ 下 ,你要掌握的重点内容。
⾝份认证的主要场景可以分为:对外认证和对内认证。其中 ,对内认证往往会因为管理的疏忽 ,导致很严重的问题。 从威胁上来说 ,⽆认证和弱密码 ,是最普遍的安全问题。 除此之外 ,各种密码和认证信息的窃取,也是⿊客常⽤的攻击⼿段。 对于⾝份认证来说 ,单点登录是⼀种集⼤成的解决⽅案。 基于CAS流程 ,衍⽣出了很多成熟的单点登录流程 ,可以供你去使⽤ 。
那么 ,掌握⾝份认证的⼀ 些技巧 ,对我们有哪些帮助呢?⾸先 ,任何的应⽤都会存在对内和对外的认证 ,因 此 ,这将是你提升应⽤安全⽔平的⼀ 个⾸要任务。其次 ,在复杂的应⽤系统和⽹络结构中 ,如何管理⾝份认 证 ,既优化⽤⼾体验 ,⼜保证其安全性 ,对你的设计和管理能⼒都是⼀ 个考验。做好了⾝份认证 ,不论是在安全上 ,还是在个⼈能⼒上 ,你都能够得到极⼤的提升。