關於 RESTFUL API 安全認證方式的一些總結


常用認證方式

在之前的文章REST API 安全設計指南使用 AngularJS & NodeJS 實現基於 token 的認證應用兩篇文章中,[譯]web權限驗證方法說明中也詳細介紹,一般基於REST API 安全設計常用方式有:
HTTP Basic

Basic admin:admin
Basic YWRtaW46YWRtaW4=
Authorization: Basic YWRtaW46YWRtaW4=

由於HTTP協議是無狀態的,所有每次請求都得帶上身份信息,基於Http basic驗證就是簡單的將用戶名和密碼base64編碼放到header中,一般需要HTTPS,安全性較低,實現的方式可以基於代碼實現也可以基於web容器配置apache,nginx等web服務器即可實現。

HTTP Digest

摘要認證 digest authentication,服務器端以nonce進行質詢,客戶端以用戶名,密碼,nonce,HTTP方法,請求的URI等信息為基礎產生的response信息進行認證的方式。
    ※ 不包含密碼的明文傳遞
    摘要認證步驟:
     1. 客戶端訪問一個受http摘要認證保護的資源。
     2. 服務器返回401狀態以及nonce等信息,要求客戶端進行認證。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
realm="testrealm@host.com",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
     3. 客戶端將以用戶名,密碼,nonce值,HTTP方法, 和被請求的URI為校驗值基礎而加密(默認為MD5算法)的摘要信息返回給服務器。
           認證必須的五個情報:
・ realm : 響應中包含信息
・ nonce : 響應中包含信息
・ username : 用戶名
・ digest-uri : 請求的URI
・ response : 以上面四個信息加上密碼信息,使用MD5算法得出的字符串。

Authorization: Digest
username="Mufasa", ← 客戶端已知信息
realm="testrealm@host.com", ← 服務器端質詢響應信息
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ← 服務器端質詢響應信息
uri="/dir/index.html", ← 客戶端已知信息
qop=auth, ← 服務器端質詢響應信息
nc=00000001, ← 客戶端計算出的信息
cnonce="0a4f113b", ← 客戶端計算出的客戶端nonce
response="6629fae49393a05397450978507c4ef1", ← 最終的摘要信息 ha3
opaque="5ccc069c403ebaf9f0171e9517f40e41" ← 服務器端質詢響應信息
     4. 如果認證成功,則返回相應的資源。如果認證失敗,則仍返回401狀態,要求重新進行認證。

     注意事項:
     1. 避免將密碼作為明文在網絡上傳遞,相對提高了HTTP認證的安全性。
     2. 當用戶為某個realm首次設置密碼時,服務器保存的是以用戶名,realm,密碼為基礎計算出的哈希值(ha1),而非密碼本身。
     3. 如果qop=auth-int,在計算ha2時,除了包括HTTP方法,URI路徑外,還包括請求實體主體,從而防止PUT和POST請求表示被人篡改。
     4. 但是因為nonce本身可以被用來進行摘要認證,所以也無法確保認證后傳遞過來的數據的安全性。

   ※ nonce:隨機字符串,每次返回401響應的時候都會返回一個不同的nonce。
   ※ nounce:隨機字符串,每個請求都得到一個不同的nounce。
      ※ MD5(Message Digest algorithm 5,信息摘要算法)
         1)用戶名:realm:密碼 ⇒ ha1
         2)HTTP方法:URI ⇒ ha2
         3)ha1:nonce:nc:cnonce:qop:ha2 ⇒ ha3

WSSE(WS-Security)

    WSSE UsernameToken
    服務器端以nonce進行質詢,客戶端以用戶名,密碼,nonce,HTTP方法,請求的URI等信息為基礎產生的response信息進行認證的方式。
    ※ 不包含密碼的明文傳遞
    WSSE認證步驟:
     1. 客戶端訪問一個受WSSE認證保護的資源。
     2. 服務器返回401狀態,要求客戶端進行認證。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: WSSE
realm="testrealm@host.com",
profile="UsernameToken" ← 服務器期望你用UsernameToken規則生成回應
※ UsernameToken規則:客戶端生成一個nonce,然后根據該nonce,密碼和當前日時來算出哈希值。
     3. 客戶端將生成一個nonce值,並以該nonce值,密碼,當前日時為基礎,算出哈希值返回給服務器。
Authorization: WSSE profile="UsernameToken"
X-WSSE:UsernameToken
username="Mufasa",
PasswordDigest="Z2Y......",
Nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
Created="2010-01-01T09:00:00Z"
     4. 如果認證成功,則返回相應的資源。如果認證失敗,則仍返回401狀態,要求重新進行認證。

API KEY

一般會分配app_key,sign_key兩個值,將通知過來的所有參數,除去sign本身,以及值是空的參數,按參數名字母升序排序,然后按參鍵值…參數n值n的方式進行連接,
得到一個字符串然后在連接后得到的字符串前面加上通知驗證密鑰(sign_key, 不同於app_key),然后計算sha1值,轉成小寫
比如請求的參數為:
?sign=9987e6395c239a48ac7f0d185c525ee965e591a7&verifycode=123412341234&app_key=ca2bf41f1910a9c359370ebf87caeafd&poiid=12345&time
stamp=1384333143&poiname= 海底撈(朝陽店)&v=1
去掉sign參數,其余的按參數名升序排列:app_keyca2bf41f1910a9c359370ebf87caeafdpoiid12345poiname海底撈(朝陽店)timestamp1384333143v
1verifycode123412341234
假設sign_key為21be83530509abc81aa945a02bec37601cf3cc21,我們把sign_key放在上面的字符串的前面:21be83530509abc81aa945a02bec37601c
f3cc21app_keyca2bf41f1910a9c359370ebf87caeafdpoiid12345poiname海底撈(朝陽店)timestamp1384333143v1verifycode123412341234
計算sha1()結果為:9987e6395c239a48ac7f0d185c525ee965e591a7

微信V3支付與美團券(以上是美團核銷券文檔摘錄)采用此種方式,對外有一個統一的服務網關,一般如果設計到安全性重要的接口,再加上數字證書(如微信支付的退款接口),適用服務端對服務端的應用。

OAUTH 2.0

OATH2設計更側重對資源的授權,OAUTH2規范定義了Authorization Code,Resource Owner Password Credentials,Client Credentials ,Implicit Grant幾種實現方式,具體看:OAuth2.0基礎概述 ,Authorization Code 模式側重對第三方用戶資源的授權(如QQ聯合登錄,微博開放平台等),Resource Owner Password Credentials 側重對個人用戶資源授權(如App),Client Credentials 側重對客戶端的資源授權,Implicit Grant 是一種最簡化模式,如網頁中JS中調用,適用場景比較局限。

HMAC

ASP.NET Web API Security Filters

1) 先由客戶端向服務器發出一個驗證請求。
2) 服務器接到此請求后生成一個隨機數並通過網絡傳輸給客戶端(此為質疑)。
3) 客戶端將收到的隨機數提供給ePass,由ePass使用該隨機數與存儲在ePass中的密鑰進行HMAC-MD5運算並得到一個結果作為認證證據傳給服務器(此為響應)。
4) 與此同時,服務器也使用該隨機數與存儲在服務器數據庫中的該客戶密鑰進行HMAC-MD5運算,如果服務器的運算結果與客戶端傳回的響應,結果相同,則認為客戶端是一個合法用戶

JWT

JWT 是JSON Web Token簡寫,用於發送通過簽名和認證的東西,服務端可通過解析該值來驗證是否有操作權限,是否過期等安全性檢查等。

3

注:
HTTP Digest與WSSE認證來源 http-wsse和http-digest兩種認證方式的區別

支付接口安全性[服務端對服務端]

支付寶:統一接口網關,RSA雙向簽名驗證

微信:API KEY方式+數字證書

銀聯:RSA+數字證書

App適用的授權方式

  • 跟用戶沒有關系的資源 Client Credentials,HMAC或API KEY,如果Token被抓包或APIKEY被反編譯,不保證安全性,但是可以杜絕大部分的垃圾請求。
  • 跟用戶有關系的資源 Resource Owner Password Credentials
  • 基於JWT實現
  • 基於Resource Owner Password Credentials 自定義實現發放Token

ASP.NET WBAPI資源安全設計

Securing ASP.NET Web APIs

http://sddconf.com/brands/sdd/library/Securing_ASPdotNET_web_APIs.pdf

Pro ASP.NET Web API Security

服務設計參考

Github
https://developer.github.com/v3/
API V3 上線,實現 OAuth 2 認證
https://ruby-china.org/topics/25630
有贊 API 文檔【appkey與oauth2】
http://open.koudaitong.com/doc

REFER:
[譯]web權限驗證方法說明
http://segmentfault.com/a/1190000004086946
開放接口的安全驗證方案(AES+RSA)
http://wustrive2008.github.io/2015/08/21/%E5%BC%80%E6%94%BE%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%89%E5%85%A8%E9%AA%8C%E8%AF%81%E6%96%B9%E6%A1%88%28AES+RSA%29/
RESTful Api 身份認證安全性設計
http://mengkang.net/625.html

大話接口隱私與安全
https://blog.thankbabe.com/2016/06/05/donot-touch-my-url/

API 客戶端認證那些事

http://mousycoder.com/2016/02/22/api-authentication/
REST API Authentication
http://stackoverflow.com/questions/7999295/rest-api-authentication
Best Practices for securing a REST API / web service
http://stackoverflow.com/questions/7551/best-practices-for-securing-a-rest-api-web-service
Best practices for API versioning
http://stackoverflow.com/questions/389169/best-practices-for-api-versioning


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM