繼續 貼一篇之前工作中的經驗案例
AK/SK簡單實戰
項目中,平台需要上下級級聯傳輸數據,發起請求時,需要進行安全認證,最終的認證方案 設計如下。
1 基本概念
APP ID :用戶id, 會在網絡傳輸中出現,(因為域管設計的是http請求,所以容易暴露),用於識別用戶身份。每個域管都有個全局唯一標識碼-indexCode,使用此標識作為APP ID。
APP key : 用戶的key, 可以有多個,每個key對應一組權限,邊緣域的API代理不需做權限細分,所以此處APP ID = APP key。
APP Secret: 用戶的秘鑰,支持重置,要保證不容易被窮舉,生成算法不容易被猜到,禁止在網絡上傳輸,用戶需要妥善保存,防止被竊,否則有泄密風險。目前簡化設計,同一域管下所有用戶使用相同的key, 不同域管使用不同的key, key一旦被重置,之前的key就會失效。
token : 在使用ak/sk 登陸認證通過后,返回token 給客戶端,token有有效期限制,有效期內直接使用token調用接口即可,當請求量非常大時,能有效降低服務器壓力。因為域管設計的是http請求,容易暴露token, 且目前請求量不大,所以這里不用token。
2 上下級級聯配置
APP ID = APP key=域管全局唯一標識碼-indexCode 是上級域管的固定值,一個隨機生成的32位uuid,生成后不再改變。
APP Secret 需要由下級生成,拷貝配置到上級。下級若重置了secret, 上級需要重新配置,否則無法訪問下級數據。
3 通訊協議
u HTTP請求頭需指定Content-Type:application/json。
u 字符編碼:utf-8
u HTTP請求參數(GET時放在querystring中,POST時放置在body 的json中)必選參數:
參數名 |
類型 |
描述 |
ts |
long |
進行接口調用時的時間戳,即當前時間戳 (時間戳:當前距離Epoch(1970年1月1日) 以秒計算的時間,即unix-timestamp),服務端會校驗時間戳,例如時間差超過20分鍾則認為請求無效,防止重復請求的攻擊 |
nonce |
long |
隨機數,與ts相配合,以保證每次請求生成的簽名都不一樣 |
appid |
string |
域管全局唯一標識碼-indexCode,用於標識哪個域管發來的請求 |
u HTTP 請求頭必須加上Authorization字段,字段內容為簽名(其中“Sign ”是 值):
Authorization:Sign bhCQXTVyfj5cmA9uKkPFx1zeOXM=
² 簽名計算方法:
GET請求POST請求::
待簽名串為整個url參數:ts=1374908054&nonce=4587954&appid=xxxxx¶m=xxxx
計算簽名:
使用HMAC-SHA256簽名算法,將app secret作為算法的key,生成待簽名串的簽名。
將得到的簽名BASE64編碼后設置到Authorization頭中(其中“Sign ”是 值):
Authorization:Sign bhCQXTVyfj5cmA9uKkPFx1zeOXM=
4 簽名校驗
下級域(服務器)收到上級域(客戶端)的請求后,使用自身的app secret ,按上述簽名計算方法,計算出簽名, 與Authorization 中的簽名值比對,
相同則認為請求合法,轉發請求並返回響應數據,不同則認為非法,返回error
1.1.1.2 PD-022-002 域配置
實現下級域的添加、刪除、修改操作,所有下級域存儲在一張表中;
支持生成/重置本級域密鑰,密鑰加密存儲在db中。
秘鑰約定:32位隨機UUID,秘鑰一旦重置,之前的秘鑰將無效。