在证书验证、基于JWT(Json Web Token)的身份认证、IDP(身份提供商)、SP(服务提供商)等技术中,都有一个可信的第三方,可明明是用户对资源或者服务的访问,为啥还要个第三方?
这篇文章整理了一些相关技术的案例,并尝试分析其这样设计的原因。
经典案例
01 证书 —— 整个互联网中的信任传递
目的: 解决两个节点之间的安全通信,常用的是用户访问某个具体的网站
背景:基于现有的网络协议(如http),在其基础上对信道进行加密,保证安全。这就需要两个节点之间至少持有一个对方的公钥( 用这个秘钥加密的数据只有对方的私钥能解开),然后才能建立加密的信道。
面临问题:作为用户,我不知道我以后会访问哪些网站,直接去网站获取它的秘钥需要通过网络传输,肯定不安全。操作系统也没办法提前就把信任的网站信息在出厂时就保存,因为有的网站可能还没开发出来。个人与商业网站都没办法相互取得信任。
具体说明:
- 证书颁发机构:有第三方公信的权威机构担任,作为一个信任传递的中介,终端电脑只需要建立起与证书颁发机构的信任就可以了。
- 根证书:证书颁发机构的证明,包含机构的信息,公钥,加密签名算法等。根证书会通过预装在操作系统或者浏览器的方式来与终端电脑建立信任。(所以安装不明来历的根证书是不安全的)
- 商业网站的证书(也就是我们平常说的证书):商业公司通过提供自己的运营资质与相关资料,付费后通过审查被颁发的证明。颁发机构在这个过程中通过审核商业公司的资料,建立信任,并颁发证书作为获得其信任的凭证。
信任的凭证:
- 终端与证书颁发机构之间:根证书
- 根证书终端与商业网站之间:根证书 + 证书
信任的传递:
- 终端如何信任证书颁发机构:系统或者浏览器会预装通用的颁发机构的根证书,或者系统管理员自己手动安装用户自己信任的根证书,这些根证书即代表了终端对相应证书颁发机构的信任(所以不要轻易安装未知的根证书)。
- 证书颁发机构如何信任商业网站:商业网站在颁发机构提供资料并申请证书,证书颁发机构会在过程中对公司资质进行审核,包括公司的工商注册信息等。如果审核通过,则会颁发一个对应域名的有实效的(比如2年)证书,这即是颁发机构对商业网站的信任凭证。
- 终端如何最终信任商业网站:终端在访问商业网站的时候,如果是https协议,则会下载商业网站的证书,然后进行一系列的验证:时间是否过期域名是否与当前访问一致签名颁发机构是否在自己的信任列表中(也就是系统中是否安装了该颁发机构的根证书)证书本身的签名是否有效。
相关场景:自签名证书——不通过第三方颁发机构,自己生成证书与根证书。一般用于系统的非生产环境。
- 优点:自己生成,方便快捷,且不需要付费。
- 缺点:根证书不是通用的颁发机构的,需要手动将其安装到所有发起访问的终端中,有额外的维护成本。
02 IDP/SP 身份提供商与服务提供商 —— 企业级的信任传递
目的:用户通过合法的身份访问资源和服务。
背景:统一管理身份,资源提供商不需要各自实现一套身份管理。
面临问题:企业或者平台中包含有很多不同的资源和服务,每个资源和服务都实现一套身份管理,这样操作不仅难以管理,用户体验很差,同时外部服务也无法公用已有的身份系统。
具体说明:
- 认证服务器:如果不想保存session,认证服务器会将用户的基本信息、token的开始与过期时间、一些元数据等进行签名,生成自验证的token。
- 终端用户:用户在第一次登录认证的时候会提供自己的用户名与密码,并将返回的token保存(一般是cookie),在token有效期内的后续访问只需要发送token就可以证明自己的身份。
- 资源/服务提供商:没有token的访问时,重定向到认证服务器,有token的访问则进行有效性验证。
信任的凭证:
- IDP到终端:用户在IDP中的验证信息,如用户名和密码
- IDP到SP:OAuth 2.0中第三方IDP颁发给服务提供商的client id与secret、token等可以证明身份的信息;Saml中IDP生成的xml文件。
信任的传递:
- 认证中心到终端:用户使用的用户名和密码等认证信息,并生成返回xml文件(也可以直接跳转到SP)。
- 终端到资源服务器:发送这个xml文件,证明自己的身份。
相关场景:认证与具体服务耦合场景——在业务的服务中,同时包含了用户信息与相应权限的管理。
- 优点:适合简单场景,单体服务。
- 缺点:当服务变多时,容易演变为每个服务各自为战,自己都有一套身份系统,后期难以维护,用户体验也比较差。
03. 基于JWT的认证 —— 单次会话中的信任传递
目的:用户通过合法的身份访问资源和服务
背景:用户访问资源,不想每次请求都登录
面临问题:每次请求都填写用户名和密码的用户体验不可想象http协议每次请求都是相互独立的,需要进行验证
具体说明:
- 认证服务器:认证服务器会将用户的基本信息、token的开始与过期时间、一些元数据等进行签名,生成自验证的token。
- 浏览器:用户在第一次登录认证的时候会提供自己是用户名与密码,并将返回的token保存(一般是cookie),在token有效期内的后续访问只需要发送token就可以证明自己的身份。
- 资源/服务提供商:没有token的访问时重定向到认证服务器,有token的访问则进行有效性验证,验证不需要与认证服务器再进行通信,如果是公钥token,只需要在资源服务器或者网关处保存对应的公钥即可对token进行验证。
信任的凭证: 自验证的token
信任的传递:
- 认证中心信任浏览器:验证用户名密码后生成token,保存cookie到浏览器。
- 浏览器cookie浏览器到资源服务器:发送请求的同时发送cookie中的token,token会在资源服务器或者网关进行验证,验证通过则为合法用户。
相关场景:基于session的认证——浏览器的cookie中只保存session id,没有完整的信息,服务端需要缓存session的具体信息。
- 优点:session id比较短,适用于用户信息太过庞大使得token过长的场景。
- 缺点:服务端需要额外维护所有登录的session信息,同时验证的时候需要再与认证中心进行交付。
总结:为什么需要第三方授权?
- 终端与资源服务器相互未知——终端不知道会访问那些网站,网站不知道会被哪些终端访问,于是需要一个长久运行的可信第三方建立信任。
- 资源服务器没有自己的身份管理系统——资源服务器关注与提供更好的资源访问,将身份认证服务交给更专业的服务。
- 资源服务器想提供更好的体验,更便捷的登录服务,比如使用Google,WeChate账户登录——资源服务器为提供更便捷的登录,让用户以其它已有的身份登录。
Reference:密码学基础
密码学的经典应用是对数据机密性的保护,不过在这篇文章中,我们涉及的是它的另外一个特性——不可伪造性。能够实现不可伪造性的技术不止一种:
-
非对称(公私钥)加密——在这种技术中,使用公钥加密数据,私钥解密数据是它的加密应用;同时可以使用私钥签名数据,公钥进行验证,因为私钥只有自己持有,公钥可以公开,就可以达到身份认证的目的。就好比一个人在支票上的签名,自己的笔迹是私钥,别人无法模仿;在不同银行开户时存底的签名模板是公钥,可以在不同银行存底;验签的过程就是银行将支票上的签名与存底模板进行比对的过程。
-
对称加密或者带盐Hash——在能够分享同一个秘钥,并且接受秘钥分享带来的风险的内部网络中,使用加密或者带盐Hash同样也可以实现身份验证的目的,将一份随机文本加密或者Hash后生成一个摘要,这段文本和摘要一起就组成了一个签名。
文/ThoughtWorks杨倚
转载:https://blog.csdn.net/toafu/article/details/111255790