Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > md5(window-1251) -> md5(utf-8)


Автор: Gold Dragon 24.6.2011, 07:28
В общем суть простая.. Был сайт в кодировке window-1251 и соответственно пароли в базе хэшировались в этой кодировке. Потом сайт стал в кодировке UTF-8, данные в базе конвертнул в utf-8, но вот что делать с паролями..

Есть ли возможность преобразовать md5(window-1251) в md5(utf-8)? Или всё же только перерегистрация?

Автор: MoLeX 24.6.2011, 08:49
Цитата(Gold Dragon @  24.6.2011,  07:28 Найти цитируемый пост)
Есть ли возможность преобразовать md5(window-1251) в md5(utf-8)?

только если есть исходные пароли  smile

Добавлено через 27 секунд
можно воспользоваться iconv'ом для перекодирования utf8 в cp1251.

Автор: srt 24.6.2011, 10:20
на форму входа можно обработку введённых данных в кодировке ср1251 повесить
можно вновь регистрирующихся отслеживать и тд.

Автор: Gold Dragon 24.6.2011, 10:22
Цитата(MoLeX @  24.6.2011,  09:49 Найти цитируемый пост)
можно воспользоваться iconv'ом для перекодирования utf8 в cp1251. 
я в шоке.. но кажется получилось... тогда не понимаю хэш.. ведь русская буква имеет разное числовое значение в разных кодировках...

может ещё кто подтвердит что простой iconv помогает? smile

Добавлено через 1 минуту и 22 секунды
srt, легче заставить всех восстановить пароль у кого не подходит. чем создавать обработчик smile

Автор: cutwater 24.6.2011, 10:36
Цитата(Gold Dragon @  24.6.2011,  09:22 Найти цитируемый пост)
я в шоке.. но кажется получилось... тогда не понимаю хэш.. ведь русская буква имеет разное числовое значение в разных кодировках...


А что Вас удивляет?
Правильно разное. Вы конвертируете utf-8 в cp1251 и вычисляете хеш.
Ничего удивительного.

Автор: Gold Dragon 24.6.2011, 10:43
ну я вообще-то думал что
текст в win не равно текст в utf... а значит и хеш должен быть разный.. и уже хеш в win просто не конвертируется в хеш в utf

Автор: patap 24.6.2011, 10:53
как вариант, можно в принципе, в неявном для юзеров виде, изменять пароль при входе.

1. добавить поле в базу, что-то типа новый_пароль, установить его в 0 для всех юзеров
2. юзер вводит свои данные
3.  хэшируем пароль в 1251 и в utf
4. пытаемся залогиниться, следующим запросом
Код

SELECT * FROM users WHERE (new_pass = 1 AND password = '$hash_utf') OR (new_pass = 0 AND password = '$hash_1251')

5. если юзер зашел, проверить поле new_pass
 - если оно равно 0 - то переписать старый хэш на утэфовский, и установить new_pass в 1
 - если равно 1 - ничего не делать

6. и так пока все юзере не перепишут себе хэши.

ну а новых разумется писать уже в утф.

если оно того стоит конечно...

Автор: cutwater 24.6.2011, 11:50
Цитата(Gold Dragon @  24.6.2011,  09:43 Найти цитируемый пост)
текст в win не равно текст в utf... а значит и хеш должен быть разный.. и уже хеш в win просто не конвертируется в хеш в utf 


Стоп. Стоп. Стоп. Хеш да не конвертируется. Исходная строка конвертируется, от нее берется хеш.

Автор: Gold Dragon 24.6.2011, 11:56
т.е. получается.. в базе у меня пароли в кодировке win-1251 преобразованные md5

Чтобы пароли принимались на сайте где всё теперь работает в utf-8 достаточно только преобразовать хэш в базе, так?

Автор: MoLeX 24.6.2011, 12:05
Цитата(Gold Dragon @  24.6.2011,  11:56 Найти цитируемый пост)

Чтобы пароли принимались на сайте где всё теперь работает в utf-8 достаточно только преобразовать хэш в базе, так? 

нет.

Смотри, у тебя сейчас сайт в utf8, а пароли остались в cp1251. С помощью iconv преобразовали utf8 в cp1251, а затем сделали их хэш.

Автор: Gold Dragon 24.6.2011, 12:21
так пароли то закрыты MD5 smile обратно то они не вернуться.....

Добавлено через 12 минут и 59 секунд
вот кое что написал для проверки
Код

<?php
// кодировка windiws-1251
$a = 'привет';
// конвертируем в utf-8
$b = iconv("windows-1251","UTF-8",$a);

// выводим результат
echo $a."<br>".$b;
echo "<hr>";

// хэш $a
$aa = md5($a);
// хэш $b
$bb = md5($b);

// выводим результат
echo $aa."<br>".$bb;
echo "<hr>";
 
// конвертируем хэш $aa
$aaa = iconv("windows-1251","UTF-8",$aa);

// выводим $aaa
echo $aaa;



Автор: bars80080 24.6.2011, 13:53
Цитата(Gold Dragon @  24.6.2011,  12:21 Найти цитируемый пост)
так пароли то закрыты MD5  обратно то они не вернуться.....

пользователь вводит пароль, строка в скрипте оказывается в кодировке utf-8, затем ты её конвертишь в cp1251, а от него берёшь хэш. и уже этот хэш и сравниваешь с тем хэшем, который в БД. то есть сравниваемые строки оказываются в одинаковых кодировках перед взятием хэша

Автор: Gold Dragon 24.6.2011, 14:43
bars80080, мне нужно старую базу паролей перегнать smile Всё новое конечно уже в utf-8

А пример кода я показал что хэш конвертируется и результат вроде одинаковый

Автор: bars80080 24.6.2011, 15:51
Цитата(Gold Dragon @  24.6.2011,  14:43 Найти цитируемый пост)
мне нужно старую базу паролей перегнать

не перегнать, так как у тебя нет паролей, а есть только хэши.
но можно использовать старый вариант

Автор: Gold Dragon 24.6.2011, 16:47
Цитата(bars80080 @  24.6.2011,  16:51 Найти цитируемый пост)
не перегнать, так как у тебя нет паролей, а есть только хэши.

так я про это и говорю...  smile Я тупо конвертирую сам хеш и получается тот же результат что если бы я преобразовал md5 в utf-8... Ну или в моём примере есть ошибка smile

Автор: BuShaRt 25.6.2011, 20:14
По идее преобразование хеша не может дать результата т.к. хеш это нечто иное, чем закодированная информация. Хеш просто нереально раскодировать, хотя бы потому, что он не наследует полный объем информации из искомого объекта. 

Поэтому если incov действительно подходит, то я буду крайне удивлен и пойду перечитывать все, что я знаю о хешах и кодировках в поисках того, как это вообще возможно.

Пока же я в этом не уверен - подскажу самый просто вариант реализации. 

Получая от пользователя ввод пароля мы его как обычно кешируем и сравниваем с кешем newPassword. Если не подошел то сравниваем с кешем oldPasword (я так понимаю, что как правильно перекодировать строку для проверки Вы сами знаетете) . Соответственно у нас несколько результатов.

1. Подошел newPassword - отлично, этот пользователь уже перешел на новый режим работы
2. Подошел oldPassword - отлично, пользователь успешно авторизовался и мы, в данном случаае имея только что введенный исходник пароля делаем из него новый кеш в нужной нам кодеровке для сохранения в newPassword. Хорошая работа - этот пользователь, сам того не подозревая перешел на новый режим работы. (поле oldPassword можно почистить, чтоб иметь возможность делать выборку пользователь не перешедших на новый режим)
3. Не подошли оба пароля - увы, тут мы нечем не поможем бедолаге =)

Для реализации нужно минут 30 максимум - вполне элементарные действия. После теста - надо придумать какую-нибудь маргетинговую фишку, чтоб нагнать народ. Ждем с пол года и делаем рассылку всем тем, у кого заполненно поле oldPassword , но не заполненно newPassword с информацией о том, что если они в течение недели не авторизируються на сервисе, то их аккаунт удалят.

=) Через неделю чистим аккаунты пользователей которые давно забыли про Ваш рессурс и удаляем лишний столбец из бд. Поздравляю - миграция закончена.

Автор: Gold Dragon 25.6.2011, 20:32
BuShaRt, ты всё правильно говоришь... Самое простое заставить всех перерегистрироваться. во-первых, напомнить о себе. Во-вторых, почистить базу пользователей

но(!)

Цитата(BuShaRt @  25.6.2011,  21:14 Найти цитируемый пост)
Поэтому если incov действительно подходит, то я буду крайне удивлен и пойду перечитывать все, что я знаю о хешах и кодировках в поисках того, как это вообще возможно.
Посмотри мой пример. Это то что я думаю или же всё таки я нарушил логику и пытаюсь выдать желаемое за действительное?


Автор: BuShaRt 25.6.2011, 20:41
А в переменной $a сейчас точно данные в win? 

Автор: Gold Dragon 25.6.2011, 20:42
текстовый файл в кодировке win.. сам проверь smile

Добавлено через 24 секунды
да и хеш то разны получается

Автор: BuShaRt 25.6.2011, 20:45
Сейчас проверить не могу, но как буду дома проверю - уж очень интересно стало.

Автор: Gold Dragon 25.6.2011, 21:04
BuShaRt, ну если и у тебя получится.. то я вообще в шоке smile 

Автор: Alchimik 26.6.2011, 06:44
Сравнивать то надо две последние строки. Если текст с русскими буквами - хэши различаюся, если только латинские - одинаковые.
Латинские буквы вроде кодируются одинаково и в UTF-8 и в Win1251,  отсюда и хэши однаковые.
Если я прав, и пароли у вас на сайте только из латинских букв и цифр, то конвертировать их не нужно.

Код

<?php
// кодировка windiws-1251
$win1251 = 'привет';
// конвертируем в utf-8
$win1251_utf8 = iconv("windows-1251","UTF-8",$win1251);

$win1251_md5 = md5($win1251); // хэш $a
$win1251_utf8_md5 = md5($win1251_utf8); // хэш $b
$win1251_md5_utf_8 = iconv("windows-1251","UTF-8",$win1251_md5);

echo $win1251_utf8_md5." win1251_utf8_md5 <br>";
echo $win1251_md5_utf_8. " win1251_md5_utf_8";
?>

Автор: Gold Dragon 26.6.2011, 08:00
конечно разные строчки... :( это я что-то навертел в своём коде.. Да и по логике такое не должно быть.. В общем, тему можно закрыть..

Суть простая, заставить всех перерегистрироваться. И полезно для сайта, и для заявить о себе. Да и полезно для парольной безопасности, типа чтоб все хоть раз пароли обновили..

Конечно можно отдельный модуль написать чтоб воспринимал старые пароли с последующей конвертацией их в новые, но скорее всего это лишь трата времени 

Автор: Alchimik 26.6.2011, 08:48
так у вас пароли на сайте не на латинице?

ps: мне бы совсем не понравилось, еслиб меня ни с того, ни с сего заставили регестрироваться заново...

Автор: BuShaRt 26.6.2011, 18:23
Добрался до рабочей станции. Alchimik правильно подметил - в примере строка $aaa будет равная $aa т.к. именно ее и конвертируете. Но для успешности эксперимента строка $aaa должна после конвертации стать равной $bb. 

По поводу того как теперь быть, я настоятельно не рекомендую вынуждать людей проходить повторную регистрацию - пример который я привел не вынуждает Вас писать целый модуль. Надо добавить одно поле в таблицу и написать порядка с десятка строк, чтоб все работало. После этого людей надо будет вынудить не регистрироваться заново, а просто авторизоваться (под предлогом того, что они давно не заходили на сайт). Согласитесь - войти и авторизоваться не так хлопотно как заново проходить регистрацию.

Добавлено через 8 минут и 8 секунд
Еще раз привожу алгоритм.

1. Проверяем соответствие нового пароля в utf. (этот кусок кода по идее уже есть - это авторизация по умолчанию). Если результат успешен, то все отлично, если же пароль не подошел мы вместо того, чтоб сразу переходить к пункту 3, делаем пункт 2.
2. Проверяем соответствие старого пароля. Если он подошел, то хешируем исходник в utf и сохраняем как новый пароль, почистив старый. Если же и старый пароль не подошел то переходим к пункту 3.
3. Оба пароля не подошли => пользователь ввел что-то не то.

Пункту 1 и 3 у Вас уже есть, Вам просто на время надо втиснуть между ними пункт 2.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)