前面我們有講過如何進行api的安全控制,其中包括資料加密,介面簽名等內容。詳細可以參考我的這兩篇文章《前後端api互動如何保證資料安全性》。
在簽名部分,通過時間戳的方式來判斷當前請求是否有效,目的是為了方式介面被多次使用。但是這樣並不能保證每次請求都是一次性的,今天給大家介紹下如何保證請求一次性?
首先我們來回顧一些時間戳判斷的原理:客戶端每次請求時,都需要進行簽名操作,簽名中會加上signtime引數(當前請求時間戳)。http請求從發出到達伺服器的正常時間不會很長,當伺服器收到http請求之後,首先進行簽名檢查,通過之後判斷時間戳與當前時間相比較,是否超過了一定的時間,這個時間我們可以自行決定要多長,比如1分鐘,2分鐘都可以,時間長點可以防止客戶端和伺服器時間不一致的問題,如果超過了則認為是非法的請求。
假設我們的請求有效期是1分鐘,如果黑客得到了我們的請求位址,在1分鐘之內是可以重複請求多次的,因為這種方式不能保證請求僅一次有效。
基於nonce的方式可以解決重複使用的問題,最開始知道nonce是在廣點通的介面中看到的,如下圖所示:
nonce是隨機字串,每次請求時都要保證不同,你可以用uuid,可以用別的演算法,也可以用隨機加時間戳等等,只要不重複就行。
在後端我們驗證的時候,將nonce引數儲存起來,至於是儲存在本地記憶體中,資料庫中,redis,布隆過濾器中這就看你自己的需求了。
處理http請求時,首先判斷該請求的nonce引數是否在存在,如果存在則認為是非法請求。如果不存在則是合法請求,讓後將該nonce儲存起來,防止下次重複使用。
這種方式的弊端也很明顯,那就是nonce的儲存會越來越大,驗證nonce是否存在的時間會越來越長。
如何解決儲存問題?
可以用時間戳+nonce同時使用,相互配合,取長補短。
首先我們根據時間戳判斷是否超過了一定的時間範圍,如果超過了就直接拒絕,沒有超過繼續驗證nonce是否使用過。
nonce沒使用,儲存起來,記錄乙個儲存時間,通過定時任務去清除超過了時間戳驗證的時間的nonce。這樣的話我們只需要儲存固定時間內的nonce資料,因為時間長的已經被時間戳的判斷給攔截了,nonce的驗證只需要驗證時間有效期內的即可。
偽**如下:
// 1.1獲取簽名時間,跟當前時間做對比,判斷是否超出範圍
long signtime = 1***xl;
long curtime = system.currenttimemillis();
if (curtime - signtime > 60000)
// 1.2獲取nonce判斷是否存在,以redis舉例
string nonce = "******";
if (redistemplate.haskey(nonce)) else
複製**
介面安全之簽名
第1步 將所有引數 注意是所有引數 除去sign本身,以及值是空的引數,按引數名字母公升序排序。第2步 然後把排序後的引數按引數1值1引數2值2 引數n值n 這裡的引數和值必須是傳輸引數的原始值,不能是經過處理的,如不能將 轉成 後再拼接 的方式拼接成乙個字串。第3步 把分配給接入方的驗證金鑰key...
介面安全之簽名
1.介面請求採用https的post方式,返回資訊全部採用json格式報文。2.請求和返回報文雙方約定採用utf 8編碼,並對請求引數做urlencoder。3.簽名規則 簽名在urlencoder之前做。4.商戶金鑰 207b6c6843a20c4acf7e8583b9d463c6 簽名規則 第1...
介面安全 簽名驗證
為防止第三方冒充客戶端請求伺服器,可以採用引數簽名驗證的方法 將請求引數中的各個鍵值對按照key的字串順序公升序排列 大小寫敏感 把key和value拼成一串之後最後加上金鑰,組成key1value1key2value2privatekey的格式,轉成utf 8編碼的位元組序列後計算md5,作為請求...