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

經常使用認證方式

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

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

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

HTTP Digestgit

摘要認證 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算法得出的字符串。
github

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狀態,要求從新進行認證。
web

     注意事項:
     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)apache

    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狀態,要求從新進行認證。
segmentfault

API KEYapi

通常會分配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

相關文章
相關標籤/搜索