python使用json web token (jwt)實(shí)現(xiàn)http api的加密傳輸

CSRF攻擊原理圖:


20150119003530_89131.jpg

上圖中Browse是瀏覽器,WebServerA是受信任網(wǎng)站/被攻擊網(wǎng)站A,WebServerB是惡意網(wǎng)站/攻擊網(wǎng)站B。

  • 一開始用戶打開瀏覽器,訪問受信任網(wǎng)站A,輸入用戶名和密碼登陸請求登陸網(wǎng)站A。

  • 網(wǎng)站A驗(yàn)證用戶信息,用戶信息通過驗(yàn)證后,網(wǎng)站A產(chǎn)生Cookie信息并返回給瀏覽器。

  • 用戶登陸網(wǎng)站A成功后,可以正常請求網(wǎng)站A。

  • 用戶未退出網(wǎng)站A之前,在同一瀏覽器中,打開一個TAB訪問網(wǎng)站B。

  • 網(wǎng)站B看到有人方式后,他會返回一些攻擊性代碼。

  • 瀏覽器在接受到這些攻擊性代碼后,促使用戶不知情的情況下瀏覽器攜帶Cookie(包括sessionId)信息,請求網(wǎng)站A。這種請求有可能更新密碼,添加用戶什么的操作。

    從上面CSRF攻擊原理可以看出,要完成一次CSRF攻擊,需要被攻擊者完成兩個步驟:

    1. 登陸受信任網(wǎng)站A,并在本地生成COOKIE
    2. 在不登出A的情況下,訪問危險網(wǎng)站 B。

    看到這里,你也許會說:“如果我不滿足以上兩個條件中的一個,我就不會受到CSRF的攻擊”。是的,確實(shí)如此,但你不能保證以下情況不會發(fā)生:

    1. 你不能保證你登錄了一個網(wǎng)站后,不再打開一個tab頁面并訪問另外的網(wǎng)站。
    2. 你不能保證你關(guān)閉瀏覽器了后,你本地的Cookie立刻過期,你上次的會話已經(jīng)結(jié)束。(事實(shí)上,關(guān)閉瀏覽器不能結(jié)束一個會話,但大多數(shù)人都會錯誤的認(rèn)為關(guān)閉瀏覽器就等于退出登錄/結(jié)束會話了……)
    3. 上圖中所謂的攻擊網(wǎng)站,可能是一個存在其他漏洞的可信任的經(jīng)常被人訪問的網(wǎng)站。

現(xiàn)在常見的csrf防御是有那么幾種方式:

  • 一種是在表單加上隨機(jī)token串,這種能夠避免99%的CSRF攻擊,還有1%就是首先沒有XSS攻擊。
  • 一種是附加token的基礎(chǔ)上加了refer的來源判斷,
  • 還有一種是XMLHttpRequest的請求的方式,他可以不用在表單里面加header,但是問題來了,如果你的網(wǎng)站以前經(jīng)常用的時動態(tài)加載的數(shù)據(jù),也就是ajax方式加載的,那么很容易用XMLHttpRequest在請求體里面加上先前respone返回token
  • 每次表單請求都帶驗(yàn)證碼,對于用戶體驗(yàn)這是萬萬不能的。我相信會讓用戶瘋掉的。

現(xiàn)在我們來看看HTTP api有哪幾種認(rèn)證方式,首先要明白,認(rèn)證和鑒權(quán)是不同的。認(rèn)證是判定用戶的合法性,鑒權(quán)是判定用戶的權(quán)限級別是否可執(zhí)行后續(xù)操作。這里所講的僅含認(rèn)證。認(rèn)證有如下幾種方法:

  1. 第一個是使用在HTTP規(guī)范中的Basic Auth,這個配置也是相當(dāng)?shù)暮唵?,原理是在每個請求的header中添加用戶名和密碼的字符串(格式為“username:password”,用base64編碼)。但是這種方式安全性較低,就是簡單的將用戶名和密碼base64編碼放到header中。 base64編碼前:Basic admin:adminbase64編碼后:Basic YWRtaW46YWRtaW4=放到Header中:Authorization: Basic YWRtaW46YWRtaW4=。正是因?yàn)槭呛唵蔚腷ase64編碼存儲,切記切記在這種方式下一定得注意使用ssl,不然就是裸奔了。 在某些產(chǎn)品中也是基于這種類似方式,只是沒有使用apache的basic機(jī)制,而是自己寫了認(rèn)證框架,原理還是一樣的,在一次請求中base64解碼Authorization字段,再和認(rèn)證信息做校驗(yàn)。很顯然這種方式有問題,認(rèn)證信息相當(dāng)于明文傳輸,另外也沒有防暴力破解功能。

  2. 第二個API Key是客戶端從服務(wù)端簽收一個加密的key,然后自己通過一定的算法組合加密數(shù)據(jù),服務(wù)端會根據(jù)你的來源解析key。類似:http://example.com/api?key=dfkaj134

client

Paste_Image.png

Server

Paste_Image.png

client端向服務(wù)端注冊,服務(wù)端給客戶端發(fā)送響應(yīng)的api_key以及security_key,注意保存不要泄露,然后客戶端根據(jù)api_key,secrity_key,timestrap,rest_uri采用hmacsha256算法得到一個hash值sign,構(gòu)造途中的url發(fā)送給服務(wù)端。 服務(wù)端收到該請求后,首先驗(yàn)證api_key,是否存在,存在則獲取該api_key的security_key,接著驗(yàn)證timestrap是否超過時間限制,可依據(jù)系統(tǒng)成而定,這樣就防止了部分重放攻擊,途中的rest_api是從url獲取的為/rest/v1/interface/eth0,最后計(jì)算sign值,完之后和url中的sign值做校驗(yàn)。這樣的設(shè)計(jì)就防止了數(shù)據(jù)被篡改。 通過這種API Key的設(shè)計(jì)方式加了時間戳防止了部分重放,加了校驗(yàn),防止了數(shù)據(jù)被篡改,同時避免了傳輸用戶名和密碼,當(dāng)然了也會有一定的開銷。

3 第三種是OAuth(或者OAuth2)。OAuth協(xié)議適用于為外部應(yīng)用授權(quán)訪問本站資源的情況。其中的加密機(jī)制與HTTP Digest身份認(rèn)證相比,安全性更高。使用和配置都比較復(fù)雜,這里就不涉及了。

4 第四種就是Token的機(jī)制。 在各種客戶端上每次都讓用戶提交用戶名和密碼,這有些不合理的。 通常的情況是客戶端通過一些可靠信息和服務(wù)器交換取token,這個token作為客服端再次請求的權(quán)限鑰匙,當(dāng)然token也是存在有效時間控制的。 Token通常比密碼更加長而且復(fù)雜。那么一旦獲得了token,在每次調(diào)用API的時候都要附加上它。這仍然比直接發(fā)送賬戶和密碼更加安全,哪怕是HTTPS。把token想象成一個安全的護(hù)照。你在一個安全的前臺驗(yàn)證你的身份(通過你的用戶名和密碼),如果你成功驗(yàn)證了自己,你就可以取得這個。當(dāng)你走進(jìn)大樓的時候(試圖從調(diào)用API獲取資源),你會被要求驗(yàn)證你的護(hù)照,而不是去前臺重新驗(yàn)證。

5 第五種,JWT協(xié)議似乎已經(jīng)應(yīng)用十分廣泛,JSON Web Token——一種基于token的json格式web認(rèn)證方法。JWT是一段被base64url編碼過的字符序列,并用點(diǎn)號分隔。它由三部分組成,頭部header、載荷playload與簽名sign。 服務(wù)端和客戶端都可以通過secret_key來識別信息是否被串改過。其基本的原理是,第一次認(rèn)證通過用戶名密碼,服務(wù)端簽發(fā)一個json格式的token。后續(xù)客戶端的請求都攜帶這個token,服務(wù)端僅需要解析這個token,來判別客戶端的身份和合法性。在這里JWT是用來取代服務(wù)端的Session而非客戶端Cookie的方案,當(dāng) 然對于客戶端本地存儲,HTML5提供了Cookie之外更多的解決方案(localStorage/sessionStorage),究竟采用哪種存儲 方式,其實(shí)從Js操作上來看沒有本質(zhì)上的差異,不同的選擇更多是出于安全性的考慮。

具體算法如下圖:

Paste_Image.png
JWT的主要應(yīng)用場景

身份認(rèn)證

在這種場景下,一旦用戶完成了登陸,在接下來的每個請求中包含JWT,可以用來驗(yàn)證用戶身份以及對路由,服務(wù)和資源的訪問權(quán)限進(jìn)行驗(yàn)證。由于它的開銷非常小,可以輕松的在不同域名的系統(tǒng)中傳遞,所有目前在單點(diǎn)登錄(SSO)中比較廣泛的使用了該技術(shù)。

信息交換

在通信的雙方之間使用JWT對數(shù)據(jù)進(jìn)行編碼是一種非常安全的方式,由于它的信息是經(jīng)過簽名的,可以確保發(fā)送者發(fā)送的信息是沒有經(jīng)過偽造的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容