1、引言
随着瓜子二手車相關業務的發展,公司有多個業務線都接入了IM系統,IM系統中的Socket長連接配接的安全問題變得越來越重要。本次分享正是基于此次解決Socket長連接配接身份安全認證的實踐總結而來,方案可能并不完美,但願能起到抛磚引玉的作用,希望能給您的IM系統開發帶來啟發。
學習交流:
- 移動端IM開發入門文章:《 新手入門一篇就夠:從零開發移動端IM 》
(本文同步釋出于:
http://www.52im.net/thread-2106-1-1.html)
2、原作者
封宇:瓜子二手車技術專家,中國計算機學會專業會員。主要負責瓜子即時消息解決方案及相關系統研發工作。曾供職于58同城、華北計算技術研究所,參與到家消息系統、58爬蟲系統以及多個國家級軍工科研項目的架構及研發工作。
封宇同時還分享了其它IM方面的技術實踐和總結,您可能也會感興趣:
《 從零開始搭建瓜子二手車IM系統(PPT) [附件下載下傳] 一套海量線上使用者的移動端IM架構設計實踐分享(含詳細圖文) 一個低成本確定IM消息時序的方法探讨 移動端IM中大規模群消息的推送如何保證效率、實時性?
3、系列文章
本文是IM通訊安全知識系列文章中的第7篇,總目錄如下: 即時通訊安全篇(一):正确地了解和使用Android端加密算法 即時通訊安全篇(二):探讨組合加密算法在IM中的應用 即時通訊安全篇(三):常用加解密算法與通訊安全講解 即時通訊安全篇(四):執行個體分析Android中密鑰寫死的風險 即時通訊安全篇(五):對稱加密技術在Android上的應用實踐 即時通訊安全篇(六):非對稱加密技術的原理與應用實踐 即時通訊安全篇(七):用JWT技術解決IM系統Socket長連接配接的身份認證痛點 》(本文)
4、我們面臨的技術痛點
針對我們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(尤其是移動端IM)業務的特殊性,這個流程結構并不好。
為什麼說上面的流程結構對于移動端的IM來說并不好呢?原因如下:
1)網絡不穩定:手機(移動端)的網絡很不穩定,進出地鐵可能斷網,挪動位置也可能換基站;
2)長連接配接頻繁建立和釋放:正因為1)中的原因,在一個聊天會話過程中,會經常重建立立長連接配接,進而導緻上圖裡的第3步會被頻繁執行,進而第4步也會頻繁執行;
3)系統壓力會增大:鑒于2)中的表現,将大大增加了SSO單點登陸系統的壓力(因為IM執行個體需要頻繁的調用SSO系統,進而完全用戶端長連接配接的身份合法性檢查);
4)使用者體驗也不好:長連接配接建立過程中,因SSO單點登陸系統并不屬于IM服務端執行個體範圍之内,IM服務端執行個體與SSO系統的通信等,帶來的額外通信鍊路延遲對于使用者的體驗也是一種傷害(而且SSO系統也可能短暫開小差)。
如果不通過上圖中的第4步就能完成IM長連接配接的身份合法性驗證,那這個痛點會得到極大緩解。于是,我們便想到了JWT技術。
* 題外話:如果您對移動端弱網絡的實體特性還不了解,那麼下面的文章有助于您建立起這方面的認知:
現代移動端網絡短連接配接的優化手段總結:請求速度、弱網适應、安全保障 移動端IM開發者必讀(一):通俗易懂,了解移動網絡的“弱”和“慢” 移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結5、完全搞懂什麼是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=35.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
5.4 解決JWT的簽名(Signature)
JWT的簽名部分,在
官方文檔中是如下描述的:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
上述僞碼的意義,即如下操作:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIyOWZmMDE5OGJlOGM0YzNlYTZlZTA4YjE1MGRhNTU0NC1XRUIiLCJleHAiOjE1MjI0OTE5MTV9
▲ 将上面的兩個base64編碼後的字元串都用句号‘.’連接配接在一起(頭部在前),就形成了如下字元串
最後,我們将上面拼接完的字元串用HS256算法進行加密。在加密的時候,我們還需要提供一個密鑰(secret)。
那麼,按照
上描述的方法,就可以得到我們加密後的内容:
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節:
▲ 上述截圖内容摘錄自
蘋果官方開發者文檔6、我們是怎樣使用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合法性驗證。
通過上述努力,移動端在弱網情況下的頻繁建立長連接配接的身份驗證痛點得到了解決。
7、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/af8360b83a9f8、點評
JWT其實是一項比較有争議的技術,誇它的人會說它簡單易用、成本低,極度貶低它的人會說它的安全性就像一層窗戶紙——捅一下就破了。
不可否認,跟目前流行的非對稱加密技術(大家最熟悉的
HTTPS協定就是一個典型的非對稱加密應用場景)相比,JWT技術的安全系數确實相對要低一些,因為JWT技術的本質就是對稱加密技術的應用,而非對稱加密技術出現的原因也就是為了提升對稱加密技術所不具有的一些安全性。
但非對稱加密技術這麼好,也并不意味着對稱加密技術就一無是處,因為并不是所有場景都需要用性能、架構的複雜性、運維成本來換取高安全性,還是那句話:“安全這東西,夠用就行”,而這也正是JWT這種技術仍然有其價值的原因所在。
非對稱加密技術雖然安全,但也并非理論上的無懈可擊,這世上還沒有絕對安全的算法,總之,不苛責級極緻安全的情況下,夠用便好,你說呢?
如果您對對稱加密和非對稱加密技術的還不是太了解,可以閱讀以下文章:
附錄:更多即時通訊方面的文章
如果您是IM開發初學者,強烈建議首先閱讀: 即時通訊安全方面的文章彙總如下: 即時通訊安全篇(五):對稱加密技術在Android平台上的應用實踐 傳輸層安全協定SSL/TLS的Java平台實作簡介和Demo示範 理論聯系實際:一套典型的IM通信協定設計詳解(含安全層設計) 微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解 來自阿裡OpenIM:打造安全可靠即時通訊服務的技術實踐分享 簡述實時音視訊聊天中端到端加密(E2EE)的工作原理 移動端安全通信的利器——端到端加密(E2EE)技術詳解 Web端即時通訊安全:跨站點WebSocket劫持漏洞詳解(含示例代碼) 通俗易懂:一篇掌握即時通訊的消息傳輸安全原理 IM開發基礎知識補課(四):正确了解HTTP短連接配接中的Cookie、Session和Token 快速讀懂量子通信、量子加密技術 即時通訊安全篇(七):如果這樣來了解HTTPS原理,一篇就夠了 一分鐘了解 HTTPS 到底解決了什麼問題 >> 更多同類文章 ……