在以前的文章REST API 安全設計指南與使用 AngularJS & NodeJS 實現基於 token 的認證應用兩篇文章中,[譯]web權限驗證方法說明中也詳細介紹,通常基於REST API 安全設計經常使用方式有:
HTTP Basichtml
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算法得出的字符串。githubAuthorization: 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
1) 先由客戶端向服務器發出一個驗證請求。
2) 服務器接到此請求後生成一個隨機數並經過網絡傳輸給客戶端(此爲質疑)。
3) 客戶端將收到的隨機數提供給ePass,由ePass使用該隨機數與存儲在ePass中的密鑰進行HMAC-MD5運算並獲得一個結果做爲認證證據傳給服務器(此爲響應)。
4) 與此同時,服務器也使用該隨機數與存儲在服務器數據庫中的該客戶密鑰進行HMAC-MD5運算,若是服務器的運算結果與客戶端傳回的響應,結果相同,則認爲客戶端是一個合法用戶
JWT
JWT 是JSON Web Token簡寫,用於發送經過簽名和認證的東西,服務端可經過解析該值來驗證是否有操做權限,是否過時等安全性檢查等。
注:
HTTP Digest與WSSE認證來源 http-wsse和http-digest兩種認證方式的區別
支付寶:統一接口網關,RSA雙向簽名驗證
微信:API KEY方式+數字證書
銀聯:RSA+數字證書
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