一種基于簽名算法且簡單安全的API授權(quán)機制
筆者以前在做廣告系統(tǒng)時發(fā)現(xiàn)對接的大多數(shù)平臺的廣告系統(tǒng)都是以token方式授權(quán)接口,而且這個token是一直不變的,由廣告主提供,可以說這就是裸奔的接口,只不過這種接口對安全性要求不高,這只能防止惡意調(diào)用以及驗證渠道的身份。
去年筆者寫過一個API統(tǒng)一授權(quán)平臺,為內(nèi)部服務(wù)開放接口給第三方系統(tǒng)調(diào)用提供統(tǒng)一的授權(quán)管理,除了方便管理接口授權(quán)外,沒有其它用途,但卻要花成本部署。這應(yīng)該是我做的一個最無意義的項目了。
今天介紹的API授權(quán)機制或許也是使用較為廣泛的一種API接口授權(quán)機制,記得筆者以前做微信支付功能的時候,微信提供的支付接口也使用這種方式:簽名。優(yōu)勢:簡單、不影響性能、不需要額外成本。
這種授權(quán)方法的實現(xiàn)邏輯是,授權(quán)方為每個接入平臺設(shè)置唯一的身份標(biāo)識(key)以及設(shè)置獨立密鑰,其實也就相當(dāng)于賬號密碼。要求接入方系統(tǒng)在每次發(fā)起請求都在請求頭攜帶三個參數(shù),分別是身份標(biāo)識(key)、發(fā)起請求的時間戳、以及簽名,授權(quán)方系統(tǒng)在接收到請求時校驗簽名,校驗通過才放行請求。
校驗簽名的過程為,從請求頭獲取key和時間戳,再根據(jù)密鑰通過相同算法生成簽名(調(diào)用方與授權(quán)方使用相同簽名算法),最后對比請求頭獲取的簽名是否相等,如果是則校驗成功,否則校驗失敗。
基于簽名算法的授權(quán)方法實現(xiàn)過程如下:
授權(quán)方:
1.定義簽名算法,提供簽名生成算法給接入方,并為接入方生成密鑰和身份標(biāo)識;
2.在項目中攔截需要驗證簽名的接口,從請求頭獲取時間戳和身份標(biāo)識,根據(jù)密鑰和簽名算法生成簽名,將生成的簽名與從請求頭獲取到的簽名比較,如果相同則繼續(xù)步驟3,否則拒絕請求;
3.請求時效性校驗,用當(dāng)前系統(tǒng)時間戳與從請求頭獲取到的時間戳比較,如果請求在有效時間范圍內(nèi)則放行請求,否則拒絕并響應(yīng)簽名過期。
接入方:
1.從授權(quán)方獲取對接文檔,并向授權(quán)方要密鑰和身份標(biāo)識;
2.根據(jù)文檔提供的簽名生成算法封裝簽名方法;
3.在發(fā)起請求時,將身份標(biāo)識、當(dāng)前時間戳、簽名寫入請求頭。
簽名生成算法可自定義,如將身份標(biāo)識(key)、時間戳(timestamp)和密鑰拼接在一起后,再采用一種不可逆算法對字符串進(jìn)行加密生成簽名,如MD5算法。規(guī)則越復(fù)雜就越不容易被破解。
簽名加上時間戳有什么好處?
一是為簽名添加時效性。授權(quán)方系統(tǒng)可根據(jù)請求時間戳與系統(tǒng)當(dāng)前時間戳比較,限定簽名只能在一秒內(nèi)有效,或者五秒內(nèi)有效。但要求雙方系統(tǒng)時間必須正確。
二是安全性,如果黑客攔截了你們系統(tǒng)的請求,然后修改請求再發(fā)起請求,這期間肯定是要時間的吧,所以當(dāng)系統(tǒng)接收到篡改后的請求時,簽名的有效期已經(jīng)過去了。如果改掉請求頭傳遞的時間戳,那么授權(quán)方系統(tǒng)生成的簽名就與請求頭傳遞的簽名不一樣了,請求一樣無效。
即便你知道授權(quán)方(肉雞)系統(tǒng)的簽名規(guī)則,如果你不知道密鑰,也無法生成有效的簽名。并且由于簽名采用非對稱加密算法,要想通過爆力破解出密鑰幾乎是不可能完成的事情。
那為什么用時間戳而不用格式化時間字符串呢?
這可能是考慮時區(qū)上的兼容吧,不同機房所在時區(qū)不同的話,時間就不同,但時間戳都相同。
為發(fā)揮這種授權(quán)方式的安全性,首先是生成簽名的規(guī)則必須夠復(fù)雜,然后是簽名的加密算法要不可逆,千萬不要使用Base64這種算法,最后是密鑰要足夠長足夠復(fù)雜,以確保即便在知道簽名生成規(guī)則的情況下,也不可能通過暴力破解出密鑰。
簽名規(guī)則指的是生成加密之前的簽名字符串的規(guī)則,如規(guī)則:key+密鑰+時間戳+key+密鑰。假設(shè)key為“app”,密鑰為"123",時間戳為"1111111111111",拼接生成的加密前的簽名為"app1231111111111111app123",最后通過加密算法對拼接的字符串加密就能生成最終的簽名。
每個接口都要寫一遍簽名邏輯不麻煩嗎?
不需要。對于授權(quán)方,可通過過濾器或者攔截器完成簽名驗證邏輯;對于調(diào)用方,使用不同框架有不同的方法,但我們總能想到辦法只寫一次簽名邏輯不是嗎?
本文轉(zhuǎn)載自微信公眾號「Java藝術(shù)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Java藝術(shù)公眾號。