拒絕接口裸奔!開放 HTTP API 接口簽名驗證!
- AccessKey&SecretKey (開放平臺)
- 請求身份
- 防止篡改
- 重放攻擊
- 實現
- Token&AppKey(APP)
- Token身份驗證
- Token+AppKey簽名驗證
- 實現
- 後續請求
接口安全問題
- 請求身份是否合法?
- 請求參數是否被篡改?
- 請求是否唯一?
AccessKey&SecretKey (開放平臺)
請求身份:
爲開發者分配AccessKey(開發者標識,確保唯一)和SecretKey(用於接口加密,確保不易被窮舉,生成算法不易被猜測)。
防止篡改:
參數簽名
- 按照請求參數名的字母升序排列非空請求參數(包含AccessKey),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串stringA;
- 在stringA最後拼接上Secretkey得到字符串stringSignTemp;
- 對stringSignTemp進行MD5運算,並將得到的字符串所有字符轉換爲大寫,得到sign值。
請求攜帶參數AccessKey和Sign,只有擁有合法的身份AccessKey和正確的簽名Sign才能放行。這樣就解決了身份驗證和參數篡改問題,即使請求參數被劫持,由於獲取不到SecretKey(僅作本地加密使用,不參與網絡傳輸),無法僞造合法的請求。
重放攻擊:
雖然解決了請求參數被篡改的隱患,但是還存在着重複使用請求參數僞造二次請求的隱患。
timestamp+nonce方案
nonce指唯一的隨機字符串,用來標識每個被簽名的請求。通過爲每個請求提供一個唯一的標識符,服務器能夠防止請求被多次使用(記錄所有用過的nonce以阻止它們被二次使用)。
然而,對服務器來說永久存儲所有接收到的nonce的代價是非常大的。可以使用timestamp來優化nonce的存儲。
假設允許客戶端和服務端最多能存在15分鐘的時間差,同時追蹤記錄在服務端的nonce集合。當有新的請求進入時,首先檢查攜帶的timestamp是否在15分鐘內,如超出時間範圍,則拒絕,然後查詢攜帶的nonce,如存在已有集合,則拒絕。否則,記錄該nonce,並刪除集合內時間戳大於15分鐘的nonce(可以使用redis的expire,新增nonce的同時設置它的超時失效時間爲15分鐘)。
實現:
請求接口:api.test.com/test?name=h…
客戶端
- 生成當前時間戳timestamp=now和唯一隨機字符串nonce=random
- 按照請求參數名的字母升序排列非空請求參數(包含AccessKey)stringA="AccessKey=access&home=world&name=hello&work=java×tamp=now&nonce=random";
- 拼接密鑰SecretKeystringSignTemp="AccessKey=access&home=world&name=hello&work=java×tamp=now&nonce=random&SecretKey=secret";
- MD5並轉換爲大寫sign=MD5(stringSignTemp).toUpperCase();
- 最終請求api.test.com/test?name=h…;
Token&AppKey(APP)
在APP開放API接口的設計中,由於大多數接口涉及到用戶的個人信息以及產品的敏感數據,所以要對這些接口進行身份驗證,爲了安全起見讓用戶暴露的明文密碼次數越少越好,然而客戶端與服務器的交互在請求之間是無狀態的,也就是說,當涉及到用戶狀態時,每次請求都要帶上身份驗證信息。
Token身份驗證:
- 用戶登錄向服務器提供認證信息(如賬號和密碼),服務器驗證成功後返回Token給客戶端;
- 客戶端將Token保存在本地,後續發起請求時,攜帶此Token;
- 服務器檢查Token的有效性,有效則放行,無效(Token錯誤或過期)則拒絕。
安全隱患:Token被劫持,僞造請求和篡改參數。
Token+AppKey簽名驗證:
與上面開發平臺的驗證方式類似,爲客戶端分配AppKey(密鑰,用於接口加密,不參與傳輸),將AppKey和所有請求參數組合成源串,根據簽名算法生成簽名值,發送請求時將簽名值一起發送給服務器驗證。
這樣,即使Token被劫持,對方不知道AppKey和簽名算法,就無法僞造請求和篡改參數。再結合上述的重發攻擊解決方案,即使請求參數被劫持也無法僞造二次重複請求。
實現:
登陸和退出請求流程
後續請求:
客戶端
- 和上述開放平臺的客戶端行爲類似,把AccessKey改爲token即可。
服務端
參考:
1:https://juejin.cn/post/6844904014438481933
2:https://juejin.cn/post/6911194479235956749
3:https://www.toutiao.com/i6862613086621139468/?wid=1624464794750
4:https://blog.piaoruiqing.com/2019/08/11/openapi-gateway-replay-attack/