RESTful Api 身份認證中的安全性設計探討
REST 是一種軟體架構風格。RESTful Api 是基於 HTTP 協議的 Api,是無狀態傳輸。它的核心是將所有的 Api 都理解為一個網路資源。將所有的客戶端和伺服器的狀態轉移(動作)封裝到 HTTP 請求的 Method 之中.
而本篇文章則主要是討論 RESTful Api 身份認證安全性設計.
沒有絕對的安全,這個話題很深,下文都是自己的一些理解,水平有限,如有勘誤,希望大家予以指正。
由於 RESTful Api 是基於 Http 協議的 Api,是無狀態傳輸,所以只要和使用者身份有關的請求都會帶上身份認證資訊。(很多時候客戶端事先並不知道某個 api 後期會不會加入身份判斷,所以我們一般都會選擇每個請求都會帶上認證資訊,如果有的話。
Http Basic Authentication
Http Basic 是一種比較簡單的身份認證方式。在 Http header 中新增鍵值對 Authorization: Basic xxx (xxx 是 username:passowrd base64 值)。
例如 username 為 zmk ,password 為 123456,請求則如下
GET /auth/basic/ HTTP/1.1
Host: xxxxx
Authorization: Basic em1rOjEyMzQ1Ng==
而 Base64 的解碼是非常方便的,如果不使用 Https ,相當於是帳號密碼直接暴露在請求中。
危險性高,實際開發者使用的應該幾乎為 0。
順便提下 DIGEST 認證,和 BASIC 認證相差無幾,而且不適合 api 設計,實際又需要兩次請求,首次請求,伺服器端返回 401,並且帶上 nonce 值,然後客戶端再利用 username+password+nonce 預設 MD5 之後再請求。對 http 請求的作用是僅僅防止二次請求,對身份認證並沒有什麼提升。
Access Token
不知道是否應該這麼稱呼。原理即當客戶端登入完畢之後,給客戶端返回一個 token,伺服器端控制該 token 的有效期,每次請求都帶上該值,然後伺服器端做驗證,退出之後,客戶端通知服務端端銷燬 token,客戶端本地也銷燬。但是如果抓包獲取到 token,就能任意偽造請求了。
同時 api 介面還存在被第三方開發者或者公司隨意利用的風險。也就是說,別人可以非常輕易的就弄出一個你們 app 的複製版,而且還用的你們的所有資源。
危險性高,實際開發估計使用得還不少。
Api Key + Security Key + Sign
下圖是我們自己每次請求的身份認證的方式,如有不足,請大家指出。可以說是 JWT 的自定義版吧。
這裡的認證邏輯即:
使用者登入返回一個 api_key 和 security_key;
然後客戶端將 security_key 存在客戶端;
當要傳送請求之前,通過 function2 加密方法,把如圖所示的五個值一起加密,得到一個 sign;
傳送請求的時候,則將除去 security_key 之外的值,以及 sign 一起傳送給伺服器端;
伺服器端首先驗證時間戳是否有效,比如是伺服器時間戳 5 分鐘之前的請求視為無效;
然後根據 api_key 得到 sercurity_key;
最後驗證 sign。
Api key 的作用是什麼?(補)
看到有朋友在頭條問了這個問題,說下我的實際使用場景:
api key 是用來標識每個不同使用者的(也就是說 api key 和使用者 id 一一對應的),同時也用來驗證security_key 和 sign 的。
比如有 2000 萬使用者,以 redis 作為資料庫,將 api_key 為鍵,security_key 作為值,api_key 雜湊分佈(比如對末尾位字元的 ASCII 對 20 取模)到 20 個 hashes 裡。
當使用者請求過來的時候首先根據 api_key 找到對應的 hashes,首先 HEXISTS 檢查該 api_key 是否存在,存在則通過 HGET 取出該值,最後一起驗證 sign。
是否需要加上時間戳驗證?
上面的認證邏輯中加密得到簽名的時候,把時間戳加進去是為了在一定程度上遮蔽了一些無效的請求,可以略去,也可以設計的更加嚴格。如果想防止惡意的 api ddos 攻擊,這一步驗證肯定是不行的。需要做更多的驗證,比如使用者驗證,ip 驗證等。可以參考 github 的 api 的設計。它會在返回的 http 頭資訊裡帶上
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999
表示這個介面在某一時間段內,該授權使用者呼叫該介面的最大次數為 5000次,該時間段內還剩餘 4999 次。當然,這樣的驗證加上之後,在程式碼的執行效率上肯定會有所影響。
是否需要將 request_parameters 也加入到 sign 生成的演算法之中?
也不是必須的,僅僅是為了請求的真實性,減少請求的偽造,比如有人抓包拿到 http 請求之後,如果沒有驗證 sign 這步,那麼別人就可以非常簡單的修改請求的引數,而請求都會生效。
這裡將 request_parameters 也加入到簽名之中,就減少了偽造請求的可能性,但是無法杜絕,破壞者可能就非要黑你,又對逆向工程非常熟悉,找到我們加密演算法的實現,依然可以未知出合法的簽名,所以我們常說,伺服器端永遠不能相信客戶端的請求都是安全的、合法的,需要做驗證的都還是不能省略。
同時這(sign演算法)也造成了 api 介面除錯的成本,api 測試工具必須也得實現那一套演算法,或者是設定在開發環境下不做驗證。我們在配置開發環境的時候則是 vpn 連測試伺服器所在內網,然後進行測試,否則開發環境也存在被人利用的風險。
專案例項 https://github.com/zhoumengkang/netty-restful-server
JWT
JWT (JSON Web Token) 使用流程如下(圖片來自官網)
其認證機制也是登入,發放金鑰給客戶端,然後客戶端每次傳送請求的時候通過 JWT 的演算法規則組裝 JWT 的Auth Header,伺服器端作驗證。
web 授權認證的原理萬變不離其宗,都是如此。
只不過 JWT 呢,自定了一套認證協議。格式為 Header.Payload.Signature。比如 xxxxx.yyyyy.zzzzz。簽名內容是有 Header+Payload+Secret 通過 HMAC SHA256 演算法加密而成。
而請求的很多引數鍵值對都可以放在 Payload 裡面。完整講解請求看官方的介紹 http://jwt.io/introduction/
需要注意的一點,依照 JWT 的協議,只有一個 secret,無法得知該使用者是誰,所以在 secret 該值中必須要可以解碼出使用者的 id。
而我們自定義認證協議的時候 header 感覺就沒有必要了,使用什麼演算法事先定義好即可。所以我們也沒選擇這種方式而是上面的那種方式。
其他
oauth2.0 則屬於第三方認證,不在本篇的討論範疇之內,可以閱讀 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
來自:周夢康
連結: http://mengkang.net/620.html
相關文章
- 討論下 RESTful 風格 API 的路由設計RESTAPI路由
- 探討Morest在RESTful API測試的行業實踐RESTAPI行業
- Yii2.0 RESTful API 認證教程RESTAPI
- C++身份核驗介面程式碼、身份證OCR、身份證實名認證APIC++API
- 微服務下認證授權框架的探討微服務框架
- 使用JWT做RESTful API的身份驗證-Go語言實現JWTRESTAPIGo
- 實驗二 網路嗅探與身份認證
- restful api設計指南RESTAPI
- 理解RESTful Api設計RESTAPI
- C++身份證二要素實名認證api、實名認證介面C++API
- Restful API 的設計規範RESTAPI
- 圖解設計模式:身份認證場景的應用圖解設計模式
- RESTful API 設計規範RESTAPI
- RESTFUL API 安全設計指南RESTAPI
- RestFul Api 設計 之 URLRESTAPI
- 好RESTful API的設計原則RESTAPI
- GitHub 的 Restful HTTP API 設計分解GithubRESTHTTPAPI
- Java身份證實名認證、身份證識別介面讓您認證任性的“懶”Java
- laravel5.6 RESTful API系列之整合github登入認證!LaravelRESTAPIGithub
- 增強版實名認證介面-Java身份證實名認證介面程式碼-身份認證Java
- 如何利用Linux伺服器提高Web介面的身份認證安全性Linux伺服器Web
- API介面安全性設計思路API
- TRIZ理論在洗碗機設計中應用探討
- node.js -- 身份認證Node.js
- 網站漏洞修復服務商對繞過認證漏洞的探討網站
- RESTful & “優雅的”API 響應結構設計RESTAPI
- Django RESTful API設計與實踐指南DjangoRESTAPI
- 我所認為的RESTful API最佳實踐RESTAPI
- Java身份證實名認證介面解鎖認證新速度Java
- 網路滲透測試實驗二——網路嗅探與身份認證
- WebApi的建立,部署,Oauth身份認證(一)WebAPIOAuth
- ASP.NET Web API 2系列(四):基於JWT的token身份認證方案ASP.NETWebAPIJWT
- MongoDB身份認證機制揭秘!MongoDB
- 簡單探討C#中GUI程式設計的標準事件問題C#GUI程式設計事件
- Java++:安全|API介面安全性設計JavaAPI
- 第三方 API 對接如何設計介面認證?API
- 第三方API對接如何設計介面認證?API
- RESTful設計中的常見疑問REST
- 關於python中slicing的探討Python