Создание подписи (signature)

В данном форуме описаны все API, поддерживаемые нашими услугами.

Создание подписи (signature)

Сообщение sd » 20 сен 2010, 14:50

Создание подписи (signature)

При добавлении параметров к базовому URL необходимо учитывать, что параметры должны следовать строго в алфавитном порядке. Исключением является параметр signature, который обязательно должен быть последним параметром.
Ниже приводится PHP-код, который сортирует и подписывает параметры. На вход функции передаются следующие параметры:

  • $params – ассоциативный массив «параметр» => «значение»
  • $password – пароль для доступа к сайту.

Код: Выделить всё
function BuildUrlParamsWithSignature($params, $password)
{
    ksort($params);

    $url = '';

    if (!is_array($params))
        return $url;

    foreach($params as $key => $value)
    {
        $url .= $key . "=" . urlencode($value) . "&";
    }

    $signature = md5($url . "&password=".urlencode($password));

    $url .= "signature=" . $signature;

    return $url;
}


Функция возвращает строку, которую необходимо добавить к базовому URL. Обратите внимание, что в параметрах и в подписи учитывается регистр.
Аватара пользователя
sd
 
Сообщения: 5184
Зарегистрирован: 31 июл 2009, 13:11

Re: Создание подписи (signature)

Сообщение alg » 13 ноя 2010, 00:02

А примерно так будет выглядеть создание подписи на Java:

Код: Выделить всё
import java.util.*;
import java.net.URLEncoder;
import java.security.*;
import java.nio.charset.Charset;

private static String convertToHex(byte[] data)
{
    StringBuffer buf = new StringBuffer();

    for (int i = 0; i < data.length; i++)
    {
        int halfByte  = (data[i] >>> 4) & 0x0F;
        int twoHalfs = 0;

        do
        {
            if ((0 <= halfByte) && (halfByte <= 9))
                buf.append((char)('0' + halfByte));
            else
                buf.append((char)('a' + (halfByte - 10)));

            halfByte = data[i] & 0x0F;
        } while(twoHalfs++ < 1);
    }

    return buf.toString();
}

private static String buildUrlParamsWithSignature(HashMap<String, String> params, String password)
{
    String   url  = "";
    Object[] key  = params.keySet().toArray();

    // Sort parameters by key (server side functions do the same).
    Arrays.sort(key);

    try
    {
        for (int i = 0; i < key.length; i++)
        {
            if (params.get(key[i]) != null)
            {
                String value = URLEncoder.encode(params.get(key[i]).toString(), "UTF8");
               
                // Java bug workaround.
                value = value.replace("*", "%2A");
                value = value.replace("~", "%7E");
               
                url += key[i] + "=" + value + "&";
            }
        }

        MessageDigest md5 = MessageDigest.getInstance("MD5");

        md5.reset();
        md5.update((url + "&password=" + URLEncoder.encode(password, "UTF8")).getBytes());

        url += "signature=" + convertToHex(md5.digest()).toLowerCase();
    }
    catch (java.security.NoSuchAlgorithmException e)
    {
        // Обалдеть - нет алгоритма MD5.
        url = "";
    }
    catch (java.io.UnsupportedEncodingException e)
    {
        // Плохо - нет поддержки UTF8. Возможно, подойдет иная системная кодировка.
        url = "";
    }

    return url;
}

У любой аварии есть фамилия, имя и отчество.
Аватара пользователя
alg
Why so serious?
 
Сообщения: 649
Зарегистрирован: 31 июл 2009, 13:11
Откуда: Москва

Re: Создание подписи (signature)

Сообщение inilus » 12 фев 2011, 15:09

Код: Выделить всё
foreach($params as $key => $value)
    {
        $url .= $key . "=" . urlencode($value) . "&";
    }


После этого получается строка вида: http://api.comtube.ru/scripts/sms_api/s ... name=user& со знаком & в конце строки? и уже она подставляется в
Код: Выделить всё
$signature = md5($url .
Я правильно понимаю?
inilus
 
Сообщения: 5
Зарегистрирован: 03 фев 2011, 21:24

Re: Создание подписи (signature)

Сообщение sd » 12 фев 2011, 15:43

Да, правильно. Есть проблемы с подписью?
Аватара пользователя
sd
 
Сообщения: 5184
Зарегистрирован: 31 июл 2009, 13:11

Re: Создание подписи (signature)

Сообщение inilus » 12 фев 2011, 16:04

sd писал(а):Да, правильно. Есть проблемы с подписью?

Да. Пишу на ruby, видимо какими-то не теми функциями пользуюсь.

Итоговая строка:
Код: Выделить всё
http://api.comtube.ru/scripts/sms_api/sendsms.php?charset=utf-8&message=Hello%20world!&to=79853330000&type=html&username=inilus&signature=3c8b3758e5849c3280c318740c970d1a

В ответ получаю ошибку 404 Authorization failed.

Исходник:
Код: Выделить всё
# encoding: utf-8
require 'uri'
require 'digest/md5'

baseurl = 'http://api.comtube.ru/scripts/sms_api/sendsms.php'
params = {
   'charset'    =>    'utf-8',
   'message'   =>   'Hello world!',
   'to'      =>   '79853330000',
   'type'      =>   'html',
   'username'   =>   'inilus',
}

url = baseurl + '?'
params.map { |key, value| url += [key, URI.escape(value)].join('=') + '&' }
signature = Digest::MD5.hexdigest(url + '&password=' + URI.escape('password_hide'))

url += 'signature=' + signature


Есть подозрение, что результат функции URI.escape() и urlencode() не совпадают
inilus
 
Сообщения: 5
Зарегистрирован: 03 фев 2011, 21:24

Re: Создание подписи (signature)

Сообщение sd » 12 фев 2011, 16:22

Таки зачем берете MD5 от общей строки с базовым URLом? Подпись надо делать только для параметров. А уже потом результат надо добавить к базовому URL'у.
Если посмотрите на нашу функцию BuildUrlParamsWithSignature, то ей передается массив параметров, по которому, которые она подписывает и возвращает строку вида "charset=utf-8&message=Hello+world%21&to=79853330000&type=html&username=inilus&signature=8ede75f9540f886bc4100cb5afd11cff", которая потом и прибавляется к базовому URL'у.
Аватара пользователя
sd
 
Сообщения: 5184
Зарегистрирован: 31 июл 2009, 13:11

Re: Создание подписи (signature)

Сообщение inilus » 12 фев 2011, 16:31

sd писал(а):Таки зачем берете MD5 от общей строки с базовым URLом? Подпись надо делать только для параметров. А уже потом результат надо добавить к базовому URL'у.
Если посмотрите на нашу функцию BuildUrlParamsWithSignature, то ей передается массив параметров, по которому, которые она подписывает и возвращает строку вида "charset=utf-8&message=Hello+world%21&to=79853330000&type=html&username=inilus&signature=8ede75f9540f886bc4100cb5afd11cff", которая потом и прибавляется к базовому URL'у.

Да, Вы правы, всё заработало. Спасибо!
inilus
 
Сообщения: 5
Зарегистрирован: 03 фев 2011, 21:24

Re: Создание подписи (signature)

Сообщение inilus » 12 фев 2011, 16:44

Реализация на Ruby
Код: Выделить всё
# encoding: utf-8
require 'digest/md5'
require 'cgi'

# baseurl = 'http://api.comtube.ru/scripts/sms_api/sendsms.php'
#
# params = {
#    'charset' => 'utf-8',
#    'from' => 'param_from',
#    'message' => 'Hello world!',
#    'to' => 'param_to',
#    'type' => 'html',
#    'username'   => 'param_username'
# }

def buildUrlWithSignature ( params, pass, baseurl )
   url = ""
   params.map { |key, value| url += [key, CGI::escape(value)].join('=') + '&' }
   signature = Digest::MD5.hexdigest(url + '&password=' + CGI::escape('param_password'))
   url = baseurl + '?' + url + 'signature=' + signature
   puts url
end
inilus
 
Сообщения: 5
Зарегистрирован: 03 фев 2011, 21:24

Re: Создание подписи (signature)

Сообщение sibsvt » 26 май 2011, 12:07

inilus писал(а):Есть подозрение, что результат функции URI.escape() и urlencode() не совпадают


Попробовал реализовать на Perl'е, убедился, что функция uri_escape из модуля URI::Escape воцклицательный знак не заменяет на %21, в то время как PHP'шная urlencode заменяет. Возможно такая же проблема возникнет и с символами одиночной кавычки, круглых скобок и звездочки.
Пришлось написать свою функцию.
sibsvt
 
Сообщения: 1
Зарегистрирован: 21 май 2011, 22:26

Re: Создание подписи (signature)

Сообщение sd » 26 май 2011, 12:25

sibsvt писал(а):
inilus писал(а):Есть подозрение, что результат функции URI.escape() и urlencode() не совпадают


Попробовал реализовать на Perl'е, убедился, что функция uri_escape из модуля URI::Escape воцклицательный знак не заменяет на %21, в то время как PHP'шная urlencode заменяет. Возможно такая же проблема возникнет и с символами одиночной кавычки, круглых скобок и звездочки.
Пришлось написать свою функцию.

Было бы очень здорово, если вы выложили здесь perl'овую функцию вместе с вашим вариантом urlencode, создающую подпись. Может, кому-то пригодится.
Аватара пользователя
sd
 
Сообщения: 5184
Зарегистрирован: 31 июл 2009, 13:11

След.

Вернуться в API

Просмотр страницы «Кто сейчас на форуме COMTUBE»

Сейчас этот форум просматривают: Yandex [ bot ] и гости: 11