
Alex Фэils?︙
03.05.2018
20:17:05

?
03.05.2018
20:19:01

Alex Фэils?︙
03.05.2018
20:19:24
да

?
03.05.2018
20:19:57
ее тогда заюзаю

Google

Egor
03.05.2018
20:20:03
а отладчик?
в криейторе на винде в цдб шаг по несколько секунд происходит

Alex Фэils?︙
03.05.2018
20:22:53
да, это грустно

Anton
03.05.2018
20:31:39

Stanislav
03.05.2018
20:32:01

Egor
03.05.2018
20:33:45
если собирать cl.exe ?

Stanislav
03.05.2018
20:34:58

Egor
03.05.2018
20:35:21
хм, проверю
да, уже не вижу такого на самых новых версиях

Dmitry
03.05.2018
21:23:52
Здравствуйте, товарищи программисты. Есть кто свободный, кто шарит в векторах, хэшировании hmac_sha256 и base64 преобразованиях?
уже второй день отчаянно борюсь в одной проблемой, почти одолел, но опыта катастрофически не хватает в этом вопросе, подсказки нужны)

Alex Фэils?︙
03.05.2018
21:24:45
привет, задавай вопрос, кто знает, тот ответит

Vladislav
03.05.2018
21:24:53

Google


Dmitry
03.05.2018
21:30:32
ок.
Итак, у меня есть строка данных и есть ключ в виде base64.
Сначала нужно ключ преобразовать в двоичный вид из base64, затем надо выполнить hmac_sha256 над данными с полученным ключом, и преобразовать снова в base64.
У меня работает преобразование в base64 из вектора. делал так:
string tobase642(vector<unsigned char> &indata){
string temp(bin_to_base64(indata.begin()),bin_to_base64(indata.end()));
temp.append( (3 - indata.size() % 3) % 3, '=' );
temp = temp ;
return temp;
};
А вот с хэшированием засада какая-то. делаю так:
void tobinary2(string indata, vector<unsigned char> &outdata){
outdata.clear();
vector<unsigned char>temp(base64_to_bin(indata.begin()),base64_to_bin(indata.end()));
for (int i=0;i<temp.size();i++) outdata.push_back(temp[i]);
};
void hmac_sha2562(string string_data, vector<unsigned char> &outdata){
unsigned char* digest;
const char* dat = strdup(string_data.c_str());
digest = HMAC(EVP_sha256(), &outdata, outdata.size(), (unsigned char*)dat, strlen(dat), NULL, NULL);
outdata.clear();
for (int i = 0; i < 32; ++i)
{
outdata.push_back(digest[i]);
}
}
и в программе работаю так:
vector<unsigned char> transport;
tobinary2(API_SECRET, transport);
hmac_sha2562(signature, transport);
string hmaSignature = tobase642(transport);
Однако, результат получается не такой, как в рабочем примере на питоне. Вот питонный код этого участка:
hmacsignature = base64.b64encode(hmac.new(base64.b64decode( API_SECRET ), signature, hashlib.sha256).digest())
используется boost для преобразований base64 и OpenSSL для хэширований


Alex Фэils?︙
03.05.2018
21:36:10
надо попробовать проверить промежуточные вычисления и убедиться, что с ними все в порядке

Dmitry
03.05.2018
21:39:16
сложновато проверить с питоном, потому что если в плюсах я ещё как-то двигаюсь, то питон вообще тёмный лес для меня, а гугление по питону почему-то вгоняет в жуткое уныние... Суть в том, что после декодирования из base64 на питоне получается очень нелицеприятная фигня, которая может выводиться в консоль как угодно. Неплохо было бы увидеть НЕХ представление декодирования. Кстати, мысль, сейчас попробую найти как это делается. Не думаю, что на питоне будет сложно

Dmitry
03.05.2018
21:45:26
tobinary2 странная, вектору в конструктор идут f(str.begin()), f(str.end()). strdup кстати тоже ни к чему.

Dmitry
03.05.2018
21:47:53
итак, tobinary 2 выдаёт двоичный вид чуток больше, чем из питона.
я получаю:
03 89 91 76 48 26 1b 72 e6 f1 b7 6e a6 0b e1 7c 53 54 a0 16 46 5e 0c c5 da d9 8a 03 4d 82 b1 9c 00
а код на питоне даёт:
03:89:91:76:48:26:1b:72:e6:f1:b7:6e:a6:0b:e1:7c:53:54:a0:16:46:5e:0c:c5:da:d9:8a:03:4d:82:b1:9c

Alex Фэils?︙
03.05.2018
21:48:48
'\0' по ходу еще добавился в C++-версии кода

Dmitry
03.05.2018
21:49:50
как можно избавиться от него?
просто отбросить последний элемент?

Dmitry
03.05.2018
21:51:58
Что возвращает base64_to_bin?

Dmitry
03.05.2018
21:53:36
массив двоичных данных возвращает

Viacheslav
03.05.2018
21:53:47
Более хороший вопрос — что он делает с end.
В hmac_sha2562 ещё и память течёт.

Dmitry
03.05.2018
21:55:17
да хрен его знает, это же из boost взято
с памятью буду бороться позже) ща бы код рабочий получить)

Viacheslav
03.05.2018
21:55:28
И копируется всё кучу раз ?

Dmitry
03.05.2018
21:57:18
А есть в этом смысл? она где-то в библиотеках буста лежит... Просто если реально в этом есть смысл - можно заморочиться поискать, но не думаю что это целесообразно. Ведь выход получается почти такой же, как в рабочей программе

Viacheslav
03.05.2018
21:58:01
Вы в неё передаёте итератор, который указывает на элемент, находящийся сразу за выделенным куском памяти.
Если там над ним вычисления какие-то идут, то это undefined behaviour сразу.

Google

Dmitry
03.05.2018
22:00:22
о господи, как же сложна))
а почему за выделенным куском памяти? все примеры использования этого дела так описаны.
К тому же, в предыдущих частях программы есть функция
string tobase642(vector<unsigned char> &indata){
string temp(bin_to_base64(indata.begin()),bin_to_base64(indata.end()));
temp.append( (3 - indata.size() % 3) % 3, '=' );
temp = temp ;
return temp;
};
которая даёт такой же результат, как в эталоне, 1 в 1

Dmitry
03.05.2018
22:04:46
Хм, может буст как нить неправильно обрабатывает невыровненный base64?
Без trailing =

Admin
ERROR: S client not available

Dmitry
03.05.2018
22:06:03
хочу попытаться просто отбросить последний элемент вектора, пока не смог найти вменяемый код, как это осуществить
ага, сделал
теперь промежуточное значение такое же, как на питоне

Dmitry
03.05.2018
22:11:06

Viacheslav
03.05.2018
22:11:20
А, ок.

Dmitry
03.05.2018
22:12:57
hmac.new(base64.b64decode( API_SECRET ), signature, hashlib.sha256).hexdigest() на питоне выдаёт:
HASH HEX: 8c41f4fa8d189254208e3c85c86db4816d6b7efee71c51fdc138cb568a056e18
Мой код выдаёт в этом же месте:
c2c9833b2b5ce4bb8e258d3dcb40c1
сейчас посмотрю, что не так делаю...

Viacheslav
03.05.2018
22:16:35
Стоп.
&outdata?
Это же адрес самого вектора, а не указатель на начало его блока памяти.

Dmitry
03.05.2018
22:17:40
аа... бегин взять от него?

Viacheslav
03.05.2018
22:17:51
outdata.data() тогда уж.


Dmitry
03.05.2018
22:19:03
HMAC digest: 8c41f4fa8d189254208e3c85c86db4816d6b7efee71c51fdc138cb568a056e18
ага, получилось
мда уж. я получил желанный hmacsignature такой же. как в коде на питоне, но сервер всё равно говорит, что сигнатура не соответствует запросу. поразительно
возможно, в заголовках теперь проблема =(
по курлу есть спецы?
код на питоне делает запрос, который работает:
headers = { 'Authorization': header_value, 'Content-Type':'application/json; charset=utf-8' }
print "HEADERS: " + str(headers)
выдаёт:
HEADERS: {'Content-Type': 'application/json; charset=utf-8', 'Authorization': 'amx 3a7b7156e994413093e5524fd8059306:vgfVmhRBQxSJiBrX9jsYEq2UCPnnRl9XRJqzxNhBPoE=:1525386073'}
моя программа на плюсах делает так:
string header = "'Authorization': 'amx " + API_KEY + ":" +hmaSignature + ":" + nonce +"'";
printf("HEADERS: %s\n", header.c_str());
и далее курл заполняю:
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "'Content-Type': 'application/json; charset=utf-8'");
chunk = curl_slist_append(chunk, header.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 17);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"CurrencyId\": 2}");
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
и выдаёт:
HEADERS: 'Content-Type': 'application/json; charset=utf-8', 'Authorization': 'amx 3a7b7156e994413093e5524fd8059306:vgfVmhRBQxSJiBrX9jsYEq2UCPnnRl9XRJqzxNhBPoE=:1525386073'
Я пробовал кавычки ставить/убирать, скобки добавить/убавить, ничё не работает =(
отбой, победил =)

Google

Zaur
04.05.2018
02:11:33
курлык-курлык

Dmitry
04.05.2018
04:29:33
Кстати да, если base64 to bin это адаптеры итераторов, понятно откуда лишний 0. Это же 6 битное кодирование, исходные 4 символа преобразуются в три октета. Значит они за инкремент могут по два символа читать, т.е. вылезать за пределы диапазона если исходная строка неканонический base64.