Страницы

Поиск по вопросам

вторник, 9 октября 2018 г.

Подскажите простейшую хэш-функцию, реализуемую в VkScript?

VKScript – это JavaScript-подобный язык, совершенно урезанный, поддерживающий лишь несколько конструкций и операторов. Он выполняется на стороне ВКонтакте, и его код можно хранить в настройках приложения, делая его скрытым от пользователей.
Мне нужно защитить от подделок некий параметр, передаваемый с моего сервера, в браузер посетителей, и оттуда – в вызов методов ВК api.
План простой: на сервере считать хэш от этого параметра, секрета и id пользователя, который нельзя подделать при обращении к api ВКонтакте. А в коде процедуры execute проверять эту подпись. Всё бы хорошо, но md5() в VkScript, наверное, не реализовать из-за ограничений языка, числа повторов в циклах и т.п.
Подскажите хэш-функцию, пусть, не достаточно безопасную для банков, но и не примитивно взламываемую школьниками – которую можно реализовать в рамках VKScript.

VkScript поддерживает только вот такие вещи:
арифметические операции логические операции создание массивов и списков ([X,Y]) parseInt и parseDouble конкатенация (+) конструкция if фильтр массива по параметру (@.) вызовы методов API, параметр length циклы, используя оператор while методы Javascript: slice, push, pop, shift, unshift, splice, substr оператор delete присваивания элементам маcсива, например: row.user.action = "test";
Из битовых операций поддерживаются только &, |, ~, << и >>. А вот XOR'а ^, который бы очень помог, нет. Также ограничены кол-во повторов в циклах и общее время выполнения – сложные алгоритмы не реализовать.
Upd. XOR, как мне подсказали, реализуется: a xor b == (a|b)&~(a&b), так же, как и сдвиг с заполнением: a >>> b == (a >> b) & (a<<(32 - b)), при условии b < 32.


Ответ

Собственно, всё решилось хешем Дженкинса примерно в такой реализации. Код хранимой процедуры ВК:
var secret = 123456 ,uid = API.users.get()[0].id ,param = parseInt(Args.param) ,signature = parseInt(Args.signature) ,toCrypt = [ param, uid, secret] ,b ,hash = 0 ;
while( toCrypt.length) { hash = hash + toCrypt.pop(); hash = hash + (hash << 10); b = hash >> 6; hash = (hash|b)&~(hash&b); } hash = hash + (hash << 3); b = hash >> 11; hash = (hash|b)&~(hash&b); hash = hash + (hash << 15);
if( hash != signature ) return {"error":"bad signature"};
return {"result":"some $$$ data"};
С сервера в клиент передаётся параметр и подпись, вычисляемая как 32-битный хеш от важного параметра, id юзера (он логинится на сайт через ВК), и секрета (32-битное число). В хранимой процедуре можно проверить, что параметр не подделан.
Например, параметром может быть timestamp, до которого у юзера оплачена платная подписка. Получить текущее время на стороне ВК можно методом API.utils.getServertime()

Комментариев нет:

Отправить комментарий