Авторские статьи Система авторизации на Javascript

Discussion in 'Статьи' started by Xex, 26 Apr 2006.

  1. Xex

    Xex Banned

    Joined:
    10 Jul 2005
    Messages:
    108
    Likes Received:
    41
    Reputations:
    7
    Посвящается:Тем кто кричит на каждом углу, что на javascript нельзя
    ничего нормального написать и начинающим экзотико-дизигнерам.
    Интро:Как нас учили еще в 5-м классе - javascript исполняется на стороне
    клиента, следовательно мы не можем хранить никаких секретных данных.
    Жалкие попытки хранить пары login:pass в файлике pass.js, который
    инклудится в нашу страницу, выкиньте из головы сразу. Тут нас спасет
    молодая, но уже сильная наука криптография. Сразу оговорюсь что
    приведенные здесь скрипты - не очень криптоустойчывы(ибо не об этом
    речь).
    Наша задача:
    написать скрипт, который допускал только "избранных" в закрытый раздел.
    Мы могли бы дать закрытому разделу имя вроде "O4en_secre7nii_razzdel",
    но если "обиженный" мембер расскажет всем магическое имя сикрет-раздела
    или другим способом произойдет утечка информации, то необходимо будет
    придумывать новое имя разздела, НО САМОЕ ГЛАВНОЕ - НЕОБХОДИМО ОПОВЕЩАТЬ
    ЛЕГАЛЬНЫХ ПОЛЬЗОВАТЕЛЕЙ о новом имени, что очень неудобно. Что ж попробуем
    написать скрипт авторизации, который будет совершенно прозрачен для пользователя.
    Начало:Как уже упоминалось, javascript - выполняется на стороне клиента, следовательно
    необходимую страницу(закрытый раздел) мы отошлем клиенту но в зашифрованной форме=)
    и выводить будем так:
    document.write(pos), где pos="Зашифрованный текст"XOR"ключ".
    Зашифрованный текст - можем смело передавать пользователю(его устойчивость
    обусловится криптоустойчивостью вашей хеш-функции), а вот ключ будем генерить
    от пользовательского логина и пароля с помощью хеш-функции. НО!снова на сцену
    выходит проблема "обиженного пользователя", т.е. он может запомнить свой ключ
    и выложить его в паблик, следовательно при удалении пользователя или утечке
    информации мы будем менять все ключи(всех пользователей за исключением
    обиженного) и шифрованный текст.
    Теперь собственно код:
    Code:
    <html>
    <script>
    
    //Хеши пользователей, генерируются в админ странице(см.ниже)
    var lead = "\x13\x06\x15\x10\x05\x09\x17\x18\x1f\x12\x10\x03\x06\x17\x17\x0a\x1b\x1b\x0e\x0b\x08\x01\x07\x12";
    
    //Шифротекст, генерируется в админ странице(см.ниже)
    var hash = "\x52\x73\x7f\x72\x74\x64\x3e\x4e\x6f\x3b\x43\x78\x6e\x59\x67\x2d\x21\x3c";
    
    var gamma="";
    var pos="";
    var lp="";
    
    //Функция получения необходимой гаммы для расшифрования
    function decrypt(login,pass,lead)
    {
    	//
    	//Гаммирует логин и пароль
    	//lp=login+pass;
    	//
    	for (i=0;i<login.length;i++)
    	{
    		f = i%pass.length;		
    		pos=pos+String.fromCharCode(login.charCodeAt(i)^pass.charCodeAt(f));
    	}	
    	lp=pos;
    	pos="";
    
    	//Гаммирование логина^пароля с хешем пользователя, чтобы получить гамму(для расшифрования)
    	for (i=0;i<hash.length;i++)
    	{
    		f = i%lp.length;		
    		pos=pos+String.fromCharCode(lead.charCodeAt(i)^lp.charCodeAt(f));
    	}
    
    
    	gamma=pos;
    	pos="";
    
    	//Расшифрование(Гаммирование шифротекста и вышеполученной гаммы)
    	for (i=0;i<gamma.length;i++)
    	{
    		f = i%gamma.length;
    		pos=pos+String.fromCharCode(gamma.charCodeAt(i)^hash.charCodeAt(f));
    	}
    	document.write(pos);
    }
    </script>
    <form>
    login:<input type=text name=login>
    <br>pass:<input type=password name=pass>
    <br>
    <input type=submit value="Авторизоваться" onClick=decrypt(form.login.value,form.pass.value,lead)>
    </form>
    </html>
    
    Возникают вопросы:Откуда берутся хеши пользователей или шифротекст?Смотрим админку:

    Code:
    <html>
    <script>
    //source - переменная содержащая открытый текст(в нашем случае закрытую страницу)
    //как мы ее туда помещать будем не важно
    //
    var source="Hacked By WraVy...";
    //Собственно гамма, лучше выбирать ее длинше и как можно случайнее
    var gamma ="qwertyuiopasdfghjklzxcvb";
    //Ключик необходимый при утечке информации или удалении пользователя
    var key="key";
    var lp="";
    var gk="";
    var pos="";
    var hash="";
    
    //Функция генерации шифрованного текста
    function cipher()
    {
    //
    //Гаммируем гамму с ключем(для "сменности" гаммы)
    //gamma=gamma+key;
    //
    	for (i=0;i<gamma.length;i++)
    	{
    		f = i%key.length;
    		pos=pos+String.fromCharCode(gamma.charCodeAt(i)^key.charCodeAt(f));
    	}
    	gamma=pos;
    	pos="";
    
    //Гаммирование исходной строки с гаммой+ключем
    	for (i=0;i<source.length;i++)
    	{
    		f = i%gamma.length;
    		pos=pos+String.fromCharCode(gamma.charCodeAt(i)^source.charCodeAt(f));
    	}
    
    //Преобразование полученного шифра в hex вид, чтобы удобно было помещать ее на
    //главную страницу
    	for (i=0;i<source.length;i++)
    	{		
    		if(pos.charCodeAt(i)>15)
    		{
    			hash=hash+"\\x"+pos.charCodeAt(i).toString(16);
    		}else
    		{
    			hash=hash+"\\x0"+pos.charCodeAt(i).toString(16);
    		}		
    	}
    	document.write(hash);
    }
    
    //
    //Функция генерации хешей пользователей
    //
    function crypt(login,pass,gamma)
    {
    //
    //Гаммируем логин и пароль
    //lp=login+pass;
    //
    	for (i=0;i<login.length;i++)
    	{
    		f = i%pass.length;		
    		pos=pos+String.fromCharCode(login.charCodeAt(i)^pass.charCodeAt(f));
    	}	
    	lp=pos;
    	pos="";
    //
    //Гаммируем гамму и ключ
    //gk=gamma+key;
    //
    
    	for (i=0;i<gamma.length;i++)
    	{
    		f = i%key.length;
    		pos=pos+String.fromCharCode(gamma.charCodeAt(i)^key.charCodeAt(f));
    	}
    	gk=pos;
    	pos="";
    
    //Гаммирование логина+пароля с гаммой+ключем
    	for (i=0;i<gk.length;i++)
    	{
    		f = i%lp.length;		
    		pos=pos+String.fromCharCode(gk.charCodeAt(i)^lp.charCodeAt(f));
    	}
    	
    //Преобразование полученного хеша в hex вид, чтобы удобно было помещать ее на
    //главную страницу
    	for (i=0;i<gk.length;i++)
    	{		
    		if(pos.charCodeAt(i)>15)
    		{
    			hash=hash+"\\x"+pos.charCodeAt(i).toString(16);
    		}else
    		{
    			hash=hash+"\\x0"+pos.charCodeAt(i).toString(16);
    		}
    	}
    	document.write(hash);
    }
    
    </script>
    <form>
    login:<input type=text name=login>
    <br>Pass:<input type=password name=pass>
    <br><input type=submit value="Зарегистрировать(получить новый хеш-пользователя)" onClick=crypt(form.login.value,form.pass.value,gamma)>
    </form>
    <input type=button value="Шифротекст" onClick=cipher()>
    </html>
    
    Последние объяснения:Если нам необходимо удалить пользователя(предателя), то для этого достаточно сменить в
    админке "key", сгенерить заново хеши пользователей(автоматизацию здесь не писал) и сгенерить
    шифротекст. Таким образом "обиженный пльзователь" не сможет использовать старый логин и пароль
    или гамму, а остальным пользователям не нужно менять свои пары логин:пароль.
    Ауттро:Данный скрипт не рекомендуется к использованию. Суть чтива показать, что используя элементы
    криптографии, мы написали прозрачную для пользователя систему авторизации на javascript.
    P.S.Для тех кто сразу не понял:соль в том что, пользователям выдается значение хеша, зависящего
    от логина, пароля и гаммы(необходимой для расшифрования). причем этот хеш мы можем сменить так,
    что пользователям не надо менять логин:пароль.
    P.S.S.Форум немного исказил текст исходников.
     
    5 people like this.
  2. Егорыч+++

    Staff Member

    Joined:
    27 May 2002
    Messages:
    1,373
    Likes Received:
    895
    Reputations:
    20
    В принципе все правильно.. Натолкнуло даже на кое-какие идеи. Спасибо за статью...
     
  3. censored!

    censored! Green member

    Joined:
    2 Nov 2004
    Messages:
    1,160
    Likes Received:
    299
    Reputations:
    156
    Кто-то уже приводил кусок кода (с просьбой расшифровать). Там тоже проверка на контрольную сумму (типа проверка на хэш), и если все ок, то уже переход на страницу www.cайт.ru/логин/пароль/index.html
    Только всегда проблема, что страницы после авторизации занесут в избранное. Даже если предателя удалят (его страницы логин/пароль), то на JS полноценно сделать проверку - имеет он право смотреть или нет - нельзя. А если можно - нафиг JS?
     
    _________________________
  4. Егорыч+++

    Staff Member

    Joined:
    27 May 2002
    Messages:
    1,373
    Likes Received:
    895
    Reputations:
    20
    Дело не в редиректе. А в том что сама страница зашифрована. Прочитать ее, не зная, пароля нельзя. Можно конечно заниматься перебором. Но если пароли выдавать то шансев у перебора никаких не будет.