Создать нормализованную строку запроса для использования на следующих стадиях:
- Отсортировать параметры по имени в utf8, сравнивая побайтово. Параметры берутся из GET URI или из тела POST запроса (когда ContentType равен application/xwwwformurlencoded)
- URLкодировать имена и значения параметров по следующим правилам:
- Не кодировать определённые в RFC 3986 незарезервированные символы. Эти символы: Az, az, 09, минус (-), подчёркивание (_), точка (.) и тильда (~).
- Все остальные символы должны быть закодированы как %XY, где X и Y это шестнадцатеричные символы от 0 до 9 и от A до F (заглавные). Расширенные utf8 символы кодируются как %XY%ZA…
- Пробел кодируется как %20 (и не как +, как обычно делается в URL)
- Кодированные имена параметров отделяются от кодированных значений знаком равно (=, ASCIIкод 61), даже если параметр имеет пустое значение.
- Пары имя – значение разделяются символом амперсанда (&, ASCII – код 38).
- Создать строку для подписи в соответствии со следующей псевдо – грамматикой (где “\n” это ASCII – символов перевода строки):12345678910StringToSign = HTTPVerb + "\n" +ValueOfHostHeaderInLowercase + "\n" +HTTPRequestURI + "\n" +CanonicalizedQueryString# HTTPVerb - метод POST, GET, PUT или DELETE.# ValueOfHostHeaderInLowercase - параметр host из заголовка HTTP запроса.# HTTPRequestURI - компонент URI, абсолютный путь до, но не включая GET-параметров.# Для пустого пути ожидается '/'.# CanonicalizedQueryString - строка с предыдущего шага.
- Рассчитать совместимый с RFC 2104 HMAC по только что созданной строке StringToSign, используя секретный ключ партёра как ключ алгоритма, и SHA256 как способ хэширования.
- Сконвертировать полученную подпись в base64.
- Использовать результат как значение параметра check.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | function http_build_query_rfc_3986($queryData, $argSeparator='&') { $r = ''; $queryData = (array) $queryData; if(!empty($queryData)) { foreach($queryData as $k=>$queryVar) { $r .= $argSeparator; $r .= $k; $r .= '='; $r .= rawurlencode($queryVar); } } return trim($r,$argSeparator); } function sign($method, $url, $params, $secretKey, $skipPort=False) { ksort($params, SORT_LOCALE_STRING); $urlParsed = parse_url($url); $path = $urlParsed['path']; $host = isset($urlParsed['host'])? $urlParsed['host']: ""; if (isset($urlParsed['port']) && $urlParsed['port'] != 80) { if (!$skipPort) { $host .= ":{$urlParsed['port']}"; } } $method = strtoupper($method) == 'POST'? 'POST': 'GET'; $data = implode("\n", array( $method, $host, $path, http_build_query_rfc_3986($params) ) ); $signature = base64_encode( hash_hmac("sha256", "{$data}", "{$secretKey}", TRUE ) ); return $signature; } // Пример вызова: |