<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                文章來源:?[http://www.cnblogs.com/xiaochangwei/p/api.html](http://www.cnblogs.com/xiaochangwei/p/api.html) ?API接口由于需要供第三方服務調用,所以必須暴露到外網,并提供了具體請求地址和請求參數 為了防止被第別有用心之人獲取到真實請求參數后再次發起請求獲取信息,需要采取很多安全機制 1.首先: 需要采用https方式對第三方提供接口,數據的加密傳輸會更安全,即便是被破解,也需要耗費更多時間 2.其次:需要有安全的后臺驗證機制【本文重點】,達到防參數篡改+防二次請求 主要防御措施可以歸納為兩點: 對請求的合法性進行校驗 對請求的數據進行校驗 防止重放攻擊必須要保證請求僅一次有效 需要通過在請求體中攜帶當前請求的唯一標識,并且進行簽名防止被篡改。 所以防止重放攻擊需要建立在防止簽名被串改的基礎之上。 請求參數防篡改 采用https協議可以將傳輸的明文進行加密,但是黑客仍然可以截獲傳輸的數據包,進一步偽造請求進行重放攻擊。如果黑客使用特殊手段讓請求方設備使用了偽造的證書進行通信,那么https加密的內容也將會被解密。 在API接口中我們除了使用https協議進行通信外,還需要有自己的一套加解密機制,對請求參數進行保護,防止被篡改。 過程如下: 客戶端使用約定好的秘鑰對傳輸參數進行加密,得到簽名值signature,并且將簽名值也放入請求參數中,發送請求給服務端 服務端接收客戶端的請求,然后使用約定好的秘鑰對請求的參數(除了signature以外)再次進行簽名,得到簽名值autograph。 服務端對比signature和autograph的值,如果對比一致,認定為合法請求。如果對比不一致,說明參數被篡改,認定為非法請求。 因為黑客不知道簽名的秘鑰,所以即使截取到請求數據,對請求參數進行篡改,但是卻無法對參數進行簽名,無法得到修改后參數的簽名值signature。 簽名的秘鑰我們可以使用很多方案,可以采用對稱加密或者非對稱加密。 防止重放攻擊 基于timestamp的方案 每次HTTP請求,都需要加上timestamp參數,然后把timestamp和其他參數一起進行數字簽名。因為一次正常的HTTP請求,從發出到達服務器一般都不會超過60s,所以服務器收到HTTP請求之后,首先判斷時間戳參數與當前時間相比較,是否超過了60s,如果超過了則認為是非法的請求。 一般情況下,黑客從抓包重放請求耗時遠遠超過了60s,所以此時請求中的timestamp參數已經失效了。 如果黑客修改timestamp參數為當前的時間戳,則signature參數對應的數字簽名就會失效,因為黑客不知道簽名秘鑰,沒有辦法生成新的數字簽名。 但這種方式的漏洞也是顯而易見的,如果在60s之后進行重放攻擊,那就沒辦法了,所以這種方式不能保證請求僅一次有效。 基于nonce的方案 nonce的意思是僅一次有效的隨機字符串,要求每次請求時,該參數要保證不同,所以該參數一般與時間戳有關,我們這里為了方便起見,直接使用時間戳的16進制,實際使用時可以加上客戶端的ip地址,mac地址等信息做個哈希之后,作為nonce參數。 我們將每次請求的nonce參數存儲到一個“集合”中,可以json格式存儲到數據庫或緩存中。 每次處理HTTP請求時,首先判斷該請求的nonce參數是否在該“集合”中,如果存在則認為是非法請求。 nonce參數在首次請求時,已經被存儲到了服務器上的“集合”中,再次發送請求會被識別并拒絕。 nonce參數作為數字簽名的一部分,是無法篡改的,因為黑客不清楚token,所以不能生成新的sign。 這種方式也有很大的問題,那就是存儲nonce參數的“集合”會越來越大,驗證nonce是否存在“集合”中的耗時會越來越長。我們不能讓nonce“集合”無限大,所以需要定期清理該“集合”,但是一旦該“集合”被清理,我們就無法驗證被清理了的nonce參數了。也就是說,假設該“集合”平均1天清理一次的話,我們抓取到的該url,雖然當時無法進行重放攻擊,但是我們還是可以每隔一天進行一次重放攻擊的。而且存儲24小時內,所有請求的“nonce”參數,也是一筆不小的開銷。 基于timestamp和nonce的方案 nonce的一次性可以解決timestamp參數60s的問題,timestamp可以解決nonce參數“集合”越來越大的問題。 防止重放攻擊一般和防止請求參數被串改一起做,請求的Headers數據如下圖所示。 我們在timestamp方案的基礎上,加上nonce參數,因為timstamp參數對于超過60s的請求,都認為非法請求,所以我們只需要存儲60s的nonce參數的“集合”即可。 ? \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*常用接口簽名,防止參數被串改偽造.\[未加密\]\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*? 其中幾個要點 token參數\[雙方私下約定\] 請求參數排序\[sort ksort krsort asort arsort 等\] 請求參數生成關聯字符串\[http\_build\_query,自定義拼接等\] 對字符串單向加密\[md5,sha1等\] ????/\*\* ? ? ?\* 簽名 ? ? ?\* ? ? ?\* @param array $params ? ? ?\* @param string $token ? ? ?\* @return void ? ? ?\* @author skyer 405661806@qq.com ? ? ?\*/ ? ? public function \_sign($params=array(), $token=''){ ? ? ? ? $response = array('code'=>1, '簽名成功'); ? ? ? ? try{ ? ? ? ? ? ? if(!is\_array($params) || empty($params)){ ? ? ? ? ? ? ? ? throw new \\Exception('簽名參數異常'); ? ? ? ? ? ? } ? ? ? ? ? ? $params\['token'\] = $token; ? ? ? ? ? ? sort($params); ? ? ? ? ? ? $tmpstr = http\_build\_query($params); ? ? ? ? ? ? $signature = sha1($tmpstr); ? ? ? ? ? ? if(!$signature){ ? ? ? ? ? ? ? ? throw new \\Exception('簽名失敗'); ? ? ? ? ? ? } ? ? ? ? ? ? $response\['data'\] = $signature; ? ? ? ? }catch(\\Exception $e){ ? ? ? ? ? ? $response\['code'\] = 0; ? ? ? ? ? ? $response\['msg'\] = $e->getMessage(); ? ? ? ? } ? ? ? ? return $response; ? ? } ? ? /\*\* ? ? ?\* 驗簽 ? ? ?\* ? ? ?\* @param \[type\] $params ? ? ?\* @param string $token ? ? ?\* @return void ? ? ?\* @author skyer 405661806@qq.com ? ? ?\*/ ? ? public function \_vaild($params, $token=''){ ? ? ? ? $response = array('code'=>1, '驗簽成功'); ? ? ? ? try{ ? ? ? ? ? ? // fileDebug('驗簽參數: '.json\_encode($params) , '\_vaild.php'); ? ? ? ? ? ? if(!is\_array($params) || empty($params)){ ? ? ? ? ? ? ? ? throw new \\Exception('驗簽參數異常'); ? ? ? ? ? ? } ? ? ? ? ? ? $signature = $params\['signature'\]; ? ? ? ? ? ? unset($params\['signature'\]); ? ? ? ? ? ? $params\['token'\] = $token; ? ? ? ? ? ? sort($params); ? ? ? ? ? ? $tmpstr = http\_build\_query($params); ? ? ? ? ? ? $vaild = sha1($tmpstr); ? ? ? ? ? ? if($signature != $vaild){ ? ? ? ? ? ? ? ? throw new \\Exception('驗簽失敗'); ? ? ? ? ? ? } ? ? ? ? }catch(\\Exception $e){ ? ? ? ? ? ? $response\['code'\] = 0; ? ? ? ? ? ? $response\['msg'\] = $e->getMessage(); ? ? ? ? } ? ? ? ? return $response; ? ? }
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看