用JWT技术解决IM系统Socket长链接的身份认证痛点

一、引言

随着瓜子二手车相关业务的发展,公司有多个业务线都接入了IM系统,IM系统中的Socket长链接的安全问题变得愈来愈重要。本次分享正是基于这次解决Socket长链接身份安全认证的实践总结而来,方案可能并不完美,希望能起到抛砖引玉的做用,但愿能给您的IM系统开发带来启发。php

学习交流:html

- 即时通信/推送技术开发交流4群:101279154[推荐]算法

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM安全

(本文同步发布于:http://www.52im.net/thread-2106-1-1.html服务器

二、原做者

 

封宇:瓜子二手车技术专家,中国计算机学会专业会员。主要负责瓜子即时消息解决方案及相关系统研发工做。曾供职于58同城、华北计算技术研究所,参与到家消息系统、58爬虫系统以及多个国家级军工科研项目的架构及研发工做。微信

封宇同时还分享了其它IM方面的技术实践和总结,您可能也会感兴趣:网络

从零开始搭建瓜子二手车IM系统(PPT) [附件下载]架构

一套海量在线用户的移动端IM架构设计实践分享(含详细图文)app

一个低成本确保IM消息时序的方法探讨运维

移动端IM中大规模群消息的推送如何保证效率、实时性?

三、系列文章

本文是IM通信安全知识系列文章中的第7篇,总目录以下:

即时通信安全篇(一):正确地理解和使用Android端加密算法

即时通信安全篇(二):探讨组合加密算法在IM中的应用

即时通信安全篇(三):经常使用加解密算法与通信安全讲解

即时通信安全篇(四):实例分析Android中密钥硬编码的风险

即时通信安全篇(五):对称加密技术在Android上的应用实践

即时通信安全篇(六):非对称加密技术的原理与应用实践

即时通信安全篇(七):用JWT技术解决IM系统Socket长链接的身份认证痛点》(本文)

四、咱们面临的技术痛点

针对咱们IM系统中的Socket长链接的身份认证安全问题,瓜子有统一登陆认证系统SSO(即单点登录系统,原理详见《IM开发基础知识补课(一):正确理解前置HTTP SSO单点登录接口的原理》)。

咱们的IM长链接通道也利用这个系统作安全认证,结构以下图:

 

如上图所示,整个认证步骤以下:

1)用户登陆App,App从业务后台拿到单点登录系统SSO颁发的token;

2)当App须要使用IM功能时,将token传给IM客服端SDK;

3)客服端SDK跟IM Server创建长链接的时候用token进行认证;

4)IM Server请求SSO单点登录系统,确认token合法性。

* 补充:如您对SSO单点登录系统的了解知之甚少,请务必先阅读《IM开发基础知识补课(一):正确理解前置HTTP SSO单点登录接口的原理》。

咋一看,这个过程没有什么问题,可是IM(尤为是移动端IM)业务的特殊性,这个流程结构并很差。

为何说上面的流程结构对于移动端的IM来讲并很差呢?缘由以下:

1)网络不稳定:手机(移动端)的网络很不稳定,进出地铁可能断网,挪动位置也可能换基站;

2)长链接频繁创建和释放:正由于1)中的缘由,在一个聊天会话过程当中,会常常从新创建长链接,从而致使上图里的第3步会被频繁执行,进而第4步也会频繁执行;

3)系统压力会增大:鉴于2)中的表现,将大大增长了SSO单点登录系统的压力(由于IM实例须要频繁的调用SSO系统,从而彻底客户端长链接的身份合法性检查);

4)用户体验也很差:长链接创建过程当中,因SSO单点登录系统并不属于IM服务端实例范围以内,IM服务端实例与SSO系统的通讯等,带来的额外通讯链路延迟对于用户的体验也是一种伤害(并且SSO系统也可能短暂开小差)。

若是不经过上图中的第4步就能完成IM长链接的身份合法性验证,那这个痛点会获得极大缓解。因而,咱们便想到了JWT技术。

* 题外话:若是您对移动端弱网络的物理特性还不了解,那么下面的文章有助于您创建起这方面的认知:

现代移动端网络短链接的优化手段总结:请求速度、弱网适应、安全保障

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

五、彻底搞懂什么是JWT技术

5.1 基础知识

JSON Web Token(简称JWT),是一个开放安全的行业标准(详见RFC7519),能够用于多个系统之间传递安全可靠的信息(也包括本文中将要用到的传递身份认证信息的场景)。

一个完整的JWT的token字符串是什么样子的结构?

 

▲ JWT说到底也是一个token字符串,它由三部分组成:头部、载荷与签名

正如上图中所示,一个JWT的token字符串组成以下:

1)红色的为Header:指定token类型与签名类型;

2)紫色的为载荷(playload):存储用户id等关键信息;

3)蓝色的为签名:保证整个信息的完整性、可靠性(这个签名字符串,至关因而一段被加密了的密文文本,安全性就是由它来决定的)。

5.2解密JWT的头部(Header)

JWT的头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。

这能够被表示成一个JSON对象:

{

"typ": "JWT",

"alg": "HS256"

}

▲ 在这个头信息里,标明了这是一个JWT字符串,而且所用的签名算法是HS256算法

对它进行Base64编码,以后的字符串就成了JWT的Header(头部),也就是你在5.1节中看到的红色部分:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

(你能够自已试着进行Base64的加密和解决,好比用这个在线工具:http://tool.oschina.net/encrypt?type=3

5.3 解密JWT的载荷(playload)

在载荷(playload)中能够定义如下属性:

1)iss: 该JWT的签发者;

2)sub: 该JWT所面向的用户;

3)aud: 接收该JWT的一方;

4)exp(expires): 何时过时,这里是一个Unix时间戳;

5)iat(issued at): 在何时签发的。

上面的信息也能够用一个JSON对象来描述,将上面的JSON对象进行base64编码,能够获得下面的字符串。

这个字符串咱们将它称做JWT的Payload(载荷),如下字串样例就是你在5.1节中看到的紫色部分:

eyJpc3MiOiIyOWZmMDE5OGJlOGM0YzNlYTZlZTA4YjE1MGRhNTU0NC1XRUIiLCJleHAiOjE1MjI0OTE5MTV9

(你能够自已试着进行Base64的加密和解决,好比用这个在线工具:http://tool.oschina.net/encrypt?type=3

5.4 解决JWT的签名(Signature)

JWT的签名部分,在官方文档中是以下描述的:

HMACSHA256(

base64UrlEncode(header) + "." +

base64UrlEncode(payload),

secret)

上述伪码的意义,即以下操做:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIyOWZmMDE5OGJlOGM0YzNlYTZlZTA4YjE1MGRhNTU0NC1XRUIiLCJleHAiOjE1MjI0OTE5MTV9

▲ 将上面的两个base64编码后的字符串都用句号‘.’链接在一块儿(头部在前),就造成了以下字符串

最后,咱们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,咱们还须要提供一个密钥(secret)。

那么,按照RFC7519上描述的方法,就能够获得咱们加密后的内容:

P-k-vIzxElzyzFbzR4tUxAAET8xT9EP49b7hpcPazd0

▲ 这个就是咱们须要的JWT的签名部分了

5.5 签名的目的

生成JWT的token字符串的最后一步签名过程,其实是对头部以及载荷内容进行加密。

通常而言:加密算法对于不一样的输入产生的输出老是不同的。因此,若是有人对头部以及载荷的内容解码以后进行修改,再进行编码的话,那么新的头部和载荷的签名和以前的签名就将是不同的。并且,若是不知道服务器加密的时候用的密钥的话,得出来的签名也必定会是不同的。

换句话说:你的JWT字符串的安全强度,基本上就是由这个签名部分来决定的。

使用时:服务器端在接受到JWT的token字符串后,会首先用开发者指明的secret(能够理解为密码)对头部和载荷的内容用同一算法再次签名。那么服务器应用是怎么知道咱们用的是哪种算法呢?别忘了,咱们在JWT的头部中已经用alg字段指明了咱们的加密算法了。

若是服务器端对头部和载荷再次以一样方法签名以后发现,本身计算出来的签名和接受到的签名不同,那么就说明这个Token的内容被别人动过的,咱们应该拒绝这个JWT Token,返回一个HTTP 401 Unauthorized响应。

5.6 一个典型的JWT应用流程

JWT是一个怎样的流程? 先上个官方文档的图:

 

如上图所示,整个应用流程描述以下:

1)客户端使用帐户密码请求登陆接口;

2)登陆成功后服务器使用签名密钥生成JWT ,而后返回JWT给客户端;

3)客户端再次向服务端请求其余接口时带上JWT;

4)服务端接收到JWT后验证签名的有效性.对客户端作出相应的响应。

5.7 总而言之

JWT的整个技术原理,就是一个很典型的对称加密应用过程,通俗的说也就是用开发者在服务端保存的密码,对用户的id等信息进行加密并按照JWT的规则(见5.1节)组成字符串返回给用户。用户在使用时将这个字符串提交给对应的服务端,服务端取出JWT字串的头信息、载荷,用开发者指明的密码试着进行加密并获得一个字符串(即合法的JWT token),两相比较,相同则认为用户提交上来的JWT合法,不然不合法。这就是JWT的所有原理,至关简单易懂。

JWT技术的价值不在于具体的技术实现,而在于它的思想自己,尤为在异构系统、分布式系统方面,能够极大的简化安全认证的成本,包括简化架构复杂性、下降使用门槛等,由于JWT的技术原理决定了认证的过程不须要其它系统的参与,由当前实例自已就能够完成,而成认证代码极小(就是一个加密字符串的比较而已)。

它的技术思路在当前的各类开发系统中应用普遍,好比下图中微信公众号的服务接口配置里,也用到了相似的思想:

 

另外,苹果著名的APNs推送服务,也支持JWT技术,详见《基于APNs最新HTTP/2接口实现iOS的高性能消息推送(服务端篇)》第6.2节:

 

▲ 上述截图内容摘录自苹果官方开发者文档

六、咱们是怎样使用JWT技术的?

上一章节,咱们详细理解了JWT技术的原理,那么回到本文的初衷:咱们该如何使用JWT技术来解决上面所提到的通点呢?

咱们采用JWT验证IM的Socket长链接流程以下:

 

如上图所示,整个验证过程描述以下:

1)用户登陆App(使用IM客服端SDK),App从业务后台拿到SSO单点登录系统颁发的token(注意:此token还不是JWT的token,它将在第3)步中被使用并生成真正的JWT token);

2)当App须要使用IM功能时,将token传给IM客服端SDK(这是在客户端完成的,即当App的功能调用IM客服端SDK时传入);

3)IM客服端SDK将用户名及第2步中获得的token发给后台的JWT Server(签发JWT token的模块),请求JWT token;

4)收到第3)步中提交过来的token后,JWT Server会经过RPC等技术向SSO系统提交验证此token的合法性,若是合法,将用跟IM Server约定的Secret(你能够理解为这就是一个固定的密码而已),根据业务须要签发JWT token,并最终返回给IM客服端SDK(即完成第3步中的请求)。

5)后绪,IM客服端SDK将使用获得的JWT token请求IM Server验证长链接,IM Server根据约定的算法(不依赖其余系统直接用JWT的规则,加上第4)步中与JWT Server 约定的Secret)便可完成jwttoken合法性验证。

经过上述努力,移动端在弱网状况下的频繁创建长链接的身份验证痛点获得了解决。

七、JWT技术的缺点

固然,咱们之因此选择JWT技术,主要看重的仍是它简单易用,但或许正由于如此,某种程度上来讲这也恰是居致它的缺点的缘由所在。

JWT技术的缺点及建议的解决方法主要有:

1)JWT的最大缺点是服务器不保存会话状态,因此在使用期间不可能取消token或更改token的权限。也就是说,一旦JWT签发,在有效期内将会一直有效;

2)JWT自己包含认证信息(即你在第5.1节中看到的头信息、负载信息),所以一旦信息泄露,任何人均可以得到token的全部权限。为了减小盗用,JWT的有效期不宜设置太长。对于某些重要操做,用户在使用时应该每次都进行进行身份验证;

3)为了减小盗用和窃取,JWT不建议使用HTTP协议来传输代码,而是使用加密的HTTPS(SSL)协议进行传输。

如下这篇文章列了一些适用JWT的应用场景,仅供参考:

https://www.jianshu.com/p/af8360b83a9f

八、点评

JWT实际上是一项比较有争议的技术,夸它的人会说它简单易用、成本低,极度贬低它的人会说它的安全性就像一层窗户纸——捅一下就破了。

不能否认,跟当前流行的非对称加密技术(你们最熟悉的HTTPS协议就是一个典型的非对称加密应用场景)相比,JWT技术的安全系数确实相对要低一些,由于JWT技术的本质就是对称加密技术的应用,而非对称加密技术出现的缘由也就是为了提高对称加密技术所不具备的一些安全性。

但非对称加密技术这么好,也并不意味着对称加密技术就一无可取,由于并非全部场景都须要用性能、架构的复杂性、运维成原本换取高安全性,仍是那句话:“安全这东西,够用就行”,而这也正是JWT这种技术仍然有其价值的缘由所在。

非对称加密技术虽然安全,但也并不是理论上的无懈可击,这世上尚未绝对安全的算法,总之,不苛责级极致安全的状况下,够用便好,你说呢?

若是您对对称加密和非对称加密技术的还不是太了解,能够阅读如下文章:

即时通信安全篇(三):经常使用加解密算法与通信安全讲解

即时通信安全篇(六):非对称加密技术的原理与应用实践

附录:更多即时通信方面的文章

若是您是IM开发初学者,强烈建议首先阅读:

新手入门一篇就够:从零开发移动端IM

即时通信安全方面的文章汇总以下:

即时通信安全篇(一):正确地理解和使用Android端加密算法

即时通信安全篇(二):探讨组合加密算法在IM中的应用

即时通信安全篇(三):经常使用加解密算法与通信安全讲解

即时通信安全篇(四):实例分析Android中密钥硬编码的风险

即时通信安全篇(五):对称加密技术在Android平台上的应用实践

即时通信安全篇(六):非对称加密技术的原理与应用实践

即时通信安全篇(七):用JWT技术解决IM系统Socket长链接的身份认证痛点

传输层安全协议SSL/TLS的Java平台实现简介和Demo演示

理论联系实际:一套典型的IM通讯协议设计详解(含安全层设计)

微信新一代通讯安全解决方案:基于TLS1.3的MMTLS详解

来自阿里OpenIM:打造安全可靠即时通信服务的技术实践分享

简述实时音视频聊天中端到端加密(E2EE)的工做原理

移动端安全通讯的利器——端到端加密(E2EE)技术详解

Web端即时通信安全:跨站点WebSocket劫持漏洞详解(含示例代码)

通俗易懂:一篇掌握即时通信的消息传输安全原理

IM开发基础知识补课(四):正确理解HTTP短链接中的Cookie、Session和Token

快速读懂量子通讯、量子加密技术

即时通信安全篇(七):若是这样来理解HTTPS原理,一篇就够了

一分钟理解 HTTPS 到底解决了什么问题

>> 更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2106-1-1.html

相关文章
相关标签/搜索