Сложная задача на Nodejs
У нас есть очень сложная задача как раз для тебя.
Есть роутеры Huawei b311 и на них стоит:
- Версия ПО 11.0.2.2
- Версия веб-страницы WEBUI 11.0.2.1
Где-то что-то может отличаться на несколько цифр, и модель устройства может быть иной, данная прошивка устанавливается на множество устройств данного производителя.
У этой прошивки есть не отключаемая авторизация и довольно хитрая.
Задача в том что бы релизовать эту авторизацию на Nodejs.
Что у нас уже есть:
- Мы знаем что первый GET запрос при авторизации идет на адрес "/api/webserver/token"
- Он устанавливает куки и возвращает token, 32 символа из которых который нужно записать в заголовок следующего запроса
- Далее генерируется случайный хеш длинной 64 символа и отправляется на адрес /api/user/challenge_login POST запросом.
- В заголовке ответа перезаписывается token полученный из этого запроса
- В ответе мы получаем 3 нужных нам параметра salt, iterations, servernonce
- Потом при можмщи нехитрых манипуляций с CryptoJS.PBKDF2, CryptoJS.HmacSHA256 мы получаем 2 новых значения
- Далее эти значения отправляем POST запросом на /api/user/authentication_login
- И собственно все.
Что мы имеем в данный момент в плане синхронного кода:
const CryptoJS = require('crypto-js');
const request = require('co-request');
async function get_json_xml(a){
return JSON.parse(convert.xml2json(a, {compact: true, spaces: 4}));
}var tmp = await request('http://'+pl.phone_list_adm_ip+'/api/webserver/token');
var body=await get_json_xml(tmp.body);
var cook=tmp.headers['set-cookie'];
var header={'Cookie': cook[0], 'Referer': 'http://'+pl.phone_list_adm_ip+'/html/index.html', '_ResponseSource': 'Broswer', '__RequestVerificationToken': body.response.token._text.substr(32),'Content-Type':'application/x-www-form-urlencoded'};
var firstnonce=crypto.createHash('md5').digest("hex")+crypto.createHash('md5').digest("hex");
var obj={url:'http://'+pl.phone_list_adm_ip+'/api/user/challenge_login', body:'<?xml version: "1.0" encoding="UTF-8"?><request><username>admin</username><firstnonce>'+firstnonce+'</firstnonce><mode>1</mode></request>', headers: header};
var tmp= await request.post(obj);
header['__RequestVerificationToken']=tmp.headers['__requestverificationtoken'];
var data=await get_json_xml(tmp.body);
worklog(data);
var pass='admin12345';
var scarmSalt = CryptoJS.enc.Hex.parse(data.response.salt._text);
var iter = data.response.iterations._text;
var finalNonce = data.response.servernonce._text;
var authMsg = firstnonce + ',' + finalNonce + ',' + finalNonce;
var saltPassword = CryptoJS.PBKDF2(pass, scarmSalt, {keySize: 8,iterations:iter,hasher: CryptoJS.algo.SHA256});
saltPassword = saltPassword.toString();
var serverKey = CryptoJS.HmacSHA256(CryptoJS.enc.Hex.parse(saltPassword),"Server Key");
serverKey = serverKey.toString();
var spwd = CryptoJS.PBKDF2(pass, scarmSalt, {keySize: 8,iterations:iter,hasher: CryptoJS.algo.SHA256});
var ckey = CryptoJS.HmacSHA256(spwd,"Client Key");
var hasher = CryptoJS.algo.SHA256.create();
var skey = hasher.update(ckey).finalize();
var csig = CryptoJS.HmacSHA256(skey, authMsg);for (var i = 0; i < ckey.sigBytes/4; i += 1) {
ckey.words[i] = ckey.words[i] ^ csig.words[i]
}
clientProof = ckey.toString();
var obj={url:'http://'+pl.phone_list_adm_ip+'/api/user/authentication_login', body:'<?xml version: "1.0" encoding="UTF-8"?><request><clientproof>'+clientProof+'</clientproof><finalnonce>'+finalNonce+'</finalnonce></request>', headers: header};
Далее у нас не получается, и что там происходит мы не понимаем и ищем человека который может это реализовать. Так что если вы умеете и могЁте, то велкам э борд.
Если вы умеете или знаете того кто умеет пишите на почту m@mobileproxy.space с темой "Сложная задача на Nodejs" и будем сотрудничать.