[PHP] 接口請求校驗的原理

 

具體的校驗步驟能夠自定義,下面是比較直觀的一種形式:php

 

1. 客戶端:請求參數帶上時間,進行首字母排序,鏈接私鑰後,取得加密結果;html

客戶端請求時帶上這個加密結果做爲sign參數。git

2. 服務端:對sign參數進行校驗(過程同上),若是正確且在有效期內,則經過。github

 

示例程序:算法

<?php
/**
 * SignCheck : session key 對稱式 加密校驗.
 *
 * 注:公私鑰模式能夠避免私鑰被竊取.
 *
 * @farwish.com
 */

// Client:

$time = time();
$url = "b=v1&a=v2&c=v3&time={$time}";
// Client和Server通用私鑰.
$uuid = 'b9514c52-5363-4364-b73f-a2ec93ae6b34';

function getSign($url, $uuid, $encode = true)
{
    parse_str( $url, $arr );

    if (! $encode ) { 
        unset($arr['sign']);
    }   

    // 1. 參數按首字母排序
    ksort($arr, SORT_REGULAR);

    $str = http_build_query($arr);

    // 2. 參數字符串拼接私鑰(TODO自定義)
    $new_str = $str . $uuid;

    // 3. 生成新sign(TODO自定義)
    $sign = openssl_encrypt($new_str, 'AES-128-CBC', $uuid, OPENSSL_RAW_DATA, substr($uuid, 0, 16));
    return md5($sign);
}

// 4. 參數拼接sign進行請求
$client_sign = getSign($url, $uuid);
$request_url = $url . "&sign={$client_sign}";

// Server:

// 去除sign從新校驗,並檢查time有效期
$server_sign = getSign($request_url, $uuid, false);

//sleep(4);

if ( ($client_sign == $server_sign) &&
    ( (time() - $time) < 5 )
) {
    echo "{$server_sign} 有效,且在有效期內.\n";
} else {
    echo "無效請求.\n";
}

Source:https://github.com/farwish/php-lab/blob/master/lab/SignCheck.php安全

Bound in Library:https://github.com/farwish/alcon/blob/master/src/Supports/Helper.phpsession

Tests:https://github.com/farwish/alcon/blob/master/tests/Supports/HelperTest.phpui

 

小結:這種校驗方式,只有徹底知道了校驗算法的客戶端才能模擬合法請求,防止數據篡改,相對安全。加密

若是須要驗證用戶登陸的狀況,能夠使用JWT的方式。url

 

Link:http://www.cnblogs.com/farwish/p/6700518.html

相關文章
相關標籤/搜索