Съхранение на пароли

misho

Registered
Преди два дни се опитах да си сменя паролата в един сайт, тъй като я бях забравил и...изпратиха ми я в явен вид. :shock: И така възникнаха няколко въпроса:
Паролите трябва да се съхраняват хеширани (например с md5). Аз поне така знам. Има ли по-добри варианти?
Както и да се съхраняват, не е ли недопустимо изобщо да има начин за извличането на оригиналната парола (за да ми я изпратят, както е и в случая), като оставим настрана базите данни с пароли и съответните им хеш стойности?

На кратко, кой е правилният и най-сигурен начин?
 
Разбира се, че паролата не би трябвало да ти е пратят във този оригиналния вид, това означава че нещо на този сайт им куца (както се казва). Хеширана ли е един път то би трябвало, ако поискаш нова, то да е съвсем различна парола. От всичко това следва, че те не си хешират паролите на потребителите или записват оригиналите пароли във отделна таблица и при поискване им се праща (това няма логика, защо тогава изобщо хешират пароли).

Хеширането е необратим процес, никой друг освен ти би трябвало да не знаете паролота, дори и сайта би трябвало да не знае паролата ти. Това само говори за сайт, който не усигорява добра защита на свойте потребители.


На другия въпрос:

Паролите могат да бъдат хеширани по много варианти, има много начини за хаш:

- md
- sha
- hash
- т.н. (може да провериш php.net)

Много администратори ползват освен традиционите методи за хеширане, ползват и така наречните salts. Те трябва да са уникални за всеки потребител и те се добавят към паролите, някой ползват един салт за всички потребители (разбира се този салт трябва единствено администратора да го знае) и по този начин затрудняват ако някой иска да разбие хаша и да вземе паролата.

Ползва се паролата + салт = хаш.
 
Само да вметна:

Ако ползваш салт, то единствено което им остава на хакерите е да позлват brute force (на бг: проба - грешка) или ако успеят да разберат салта на потребителя, да го използват заедно със една база данни със вече въведени данни за всеки хаш - каква комбинация от символи отговаря.

Доста се отделихме от темата.
 
eddyy93 каза:
Много администратори ползват освен традиционите методи за хеширане, ползват и така наречните salts. Те трябва да са уникални за всеки потребител и те се добавят към паролите, някой ползват един салт за всички потребители (разбира се този салт трябва единствено администратора да го знае) и по този начин затрудняват ако някой иска да разбие хаша и да вземе паролата.

Ползва се паролата + салт = хаш.
Аз преди да мина паролата през md5 ѝ добавям 2-3 символа, които са си винаги едни и същи. Когато са уникални за всеки потребител, трябва и тях да ги пазя в базата. В такъв случай, ако някой достигне до базата с данни, това не прави ли разбиването една идея по-лесно (след като вече знае какво е било добавено)?
 
Защо да ги пазиш?

Салта може да е (потребителското ID + 5 ) да кажем, след това тези твойте символи могат да се добавят и те, също така паролата след като е въедена, добавяш от зад и от пред на паролата тези 2 стойности (може и друга комбинация), тоест:


( ID + 5 ) + парола + твойте символи.

И това го минаваш през някой хаш алоритъм (като например sha).
Също така може вместо ИД на потребитела, да ползваш времето в което си е създал акаунта (time() или други уникални неща, айде time може и да не е най - уникалното нещо, попринцип е възможно 2 ма едновременно да се регистритът).
 
misho каза:
eddyy93 каза:
Много администратори ползват освен традиционите методи за хеширане, ползват и така наречните salts. Те трябва да са уникални за всеки потребител и те се добавят към паролите, някой ползват един салт за всички потребители (разбира се този салт трябва единствено администратора да го знае) и по този начин затрудняват ако някой иска да разбие хаша и да вземе паролата.

Ползва се паролата + салт = хаш.
Аз преди да мина паролата през md5 ѝ добавям 2-3 символа, които са си винаги едни и същи. Когато са уникални за всеки потребител, трябва и тях да ги пазя в базата. В такъв случай, ако някой достигне до базата с данни, това не прави ли разбиването една идея по-лесно (след като вече знае какво е било добавено)?

Не, няма да го направи по-лесно. Уникалната сол те предпазва от атака на всички пароли в БД едновременно. Тоест аз ако ще брутфорсвам пароли за всяка проба ще проверявам цялата БД тоест 1 брутфорс за всички пароли, не по отделно всяка. Ако има уникална сол (без значение, че я пазиш в таблицата) това няма как да стане.
 
Е той ако пази салта във таблица, то този който вземе паролите, логично да има достъп и да вземе и салта за тях (ако ги пази във таблица).

Варианата който дадох:
потребителското ИД + прозволно число (но винаги еднакво) + паролата + салт (който се записва във някакъв run time регистър), може би ще е по - добре.
 
eddyy93 каза:
Е той ако пази салта във таблица, то този който вземе паролите, логично да има достъп и да вземе и салта за тях (ако ги пази във таблица).

Варианата който дадох:
потребителското ИД + прозволно число (но винаги еднакво) + паролата + салт (който се записва във някакъв run time регистър), може би ще е по - добре.

Както и да го смяташ ако ти има кода и БД ще го види. Но това не е проблем, че някой ти вижда солта. Въпроса е, че не може да брутфорсва накуп всички пароли, а ще трябва една по една
 
Правилно, също така може + това както казах може да създаде един собствен салт, който да го показва при поискване при регистриране и при логване във системата. Така този, който иска да вземе паролата, ще трябва да вземе не само хаша на паролата и салта от таблицата, но и салта, който е дефинирам във някакъв php файл или регистър (run time регистър).
 
Всъщност може и то с доста голяма скорост, само трябва в един файл да запише всичките хешове и салтовете и да знае типът на крайният хеш, примерно md5(md5($salt).md5($hash)), а да не говорим, че hashcat има и готови алгоритми като phpbb3 wordpress и т.н. и с някой голям wordlist от inside-a за няколко дни може да намери паролите на доста от акаунтите.
Е да това би го направил или някой психясъл "хахор" или ако достъпът до сайта ще му е наистина ценен.

Извинявам, че се отклонявам от темата, но вчера уж "бг анонимните" хакнаха сайта на "Български фармацефтичен съюз" , макар че по-скоро е някой самозванец тъй като не беше заменил страницата а беше добавил новина.
Та както и да е поиграх си аз 10 минути и се оказа че в таблицата user с над 1000 потребители всичките пароли са записани в абсолютно чист вид.
Да не говорим че на 7/8 от тези хора сигурно използват и същите пароли за email адресите си..
Така че да се запазват пароли в чист вид може да навреди на хората като не само им се откраднат акаунти, а дори и email адреси, което ще е доста неприятно..

Не е нужно да държиш salt-овете в база данни.
По-добре направи функция която да връща salt според потребителското име.
Примерно нещо такова

PHP:
<?php
function generate_salt($username)
{
$salt = '$%'.substr( strrev(md5(base64_encode($username))), 0,8 );
return $salt;
}
echo generate_salt("proba");
?>

Това ще върне $%0d363987
След това при регистрация записваш да речем следното:

PHP:
// тук функцията за генериране, можеш да я сложиш и в отделен файл и да я include
$username = htmlspecialchars($_POST['username']);
$hash = md5($_POST['password']);
$salt = generate_salt($username);
$new_hash = md5(md5($salt).md5($hash));
// mysql_query("INSERT INTO...") or die(mysql_error());

И записваш в базата данни $new_hash.
Като аз тествах с парола test и hash-ът е това:

393e1458baf5c900894111717bab83b9

И за вход си проверяваш така:

PHP:
// тук функцията за генериране, можеш да я сложиш и в отделен файл и да я include
$username = htmlspecialchars($_POST['username']);
$hash = md5($_POST['password']);
$salt = generate_salt($username);
$new_hash = md5(md5($salt).md5($hash));
// mysql_query("SELECT *...") or die(mysql_error());

(То това със сигурност ти е ясно де).

Така за абсолютно всеки потребител получаваш уникален salt без той да е записан някъде така, че само ако видят кодът на функцията биха могли да си създадат salt и да се опитват да разбият паролата..
Но те ако имат достъп да видят кодът на функцията, то тогава не виждам за какво им е паролата след като имат достъп до файловете на сайта и т.н.

Така, че се надявам това да ти е от полза.

Поздрави, Ивайло (не знам дали ме помниш, преди няколко месеца пътувахме в 1 купе във влака (до Бургас), ти беше с тениска на h*st.bg и тогава те питах дали работиш за тях, а накрая се оказа , че сме съфорумници :) )
 
Е проба единственото, което не ми харесва е това, че пускаш 2 пъти md5?

Защо го правиш, това няма логика, единствено забавя сървъра допълнително и омотава целия хаш ... При условие, че ти е генериран добър салт, не ти трябва двойното мд5. Да не говорим, че ако искаш да взимаш пароли ще опиташ такива методи със двойни и тройни хашове ...

Едит:

Също така може нещо по - различно от: $% да сложиш.

Ето един сайт, който може да позлваш за уникални салтове и изобщо уникални стрингове (поне сайта им го гарантира това):
https://www.grc.com/passwords.htm
 
Е забавя сървъра но не е чак фатално.
И го дадох за пример тъй като по-горе му споменах за md5(md5(salt).md5(password)) защото наистина някой системи така си генерират hash, след като 1 път генерират salt ( не знам на какъв принцип ) и след това отново го минават с md5.
Е да обърках се и минах md5($password) през md5 вместо само $password, просто не се усетих тъй като в същото време му правех и тест на моят localhost за да видя дали ще работи, извинявам се.
Може да се поправи това:

PHP:
$new_hash = md5(md5($salt).md5($hash));

С това:

PHP:
$new_hash = md5(md5($salt).$hash);

А относно това за $% ги сложиш за пример, и ги натиснах на случаен принцип тъй като са едно до друго.
 
proba каза:
Поздрави, Ивайло (не знам дали ме помниш, преди няколко месеца пътувахме в 1 купе във влака (до Бургас), ти беше с тениска на h*st.bg и тогава те питах дали работиш за тях, а накрая се оказа , че сме съфорумници :) )
Помня, разбира се. :)

По този начин, с функция, вече изглежда доста по-надеждно.

proba каза:
Така че да се запазват пароли в чист вид може да навреди на хората като не само им се откраднат акаунти, а дори и email адреси, което ще е доста неприятно..
То, там е бедата. Ако имаш достъп до пощата, практически имаш контрол върху всички профили по същата схема със забравената парола. Още по-лесно става, ако паролата е същата, както е в повечето случаи.
 
А ето как CakePhp правят хаша, това е метода от класа security:

Configure::read('Security.salt');

Отговаря на салта, ето пример какво съм въвел аз:

qBqZ6Z5PLLWmvAsPDfbts5RWXMjVe02tAzq9HbkMBSxqOLLiLKo2ojDiIOfGoBX

Това съм го генерирал от сайта, който показах по - горе, би трябвало никой друг в света да няма подобен.

На $hashType, може някъде от вънка на метода (ако ще ползваш сетър) или в метода, какъв тип да е хаша.


PHP:
/**
 * Create a hash from string using given method.
 * Fallback on next available method.
 *
 * @param string $string String to hash
 * @param string $type Method to use (sha1/sha256/md5)
 * @param boolean $salt If true, automatically appends the application's salt
 *     value to $string (Security.salt)
 * @return string Hash
 */
	public static function hash($string, $type = null, $salt = false) {
		if ($salt) {
			if (is_string($salt)) {
				$string = $salt . $string;
			} else {
				$string = Configure::read('Security.salt') . $string;
			}
		}

		if (empty($type)) {
			$type = self::$hashType;
		}
		$type = strtolower($type);

		if ($type == 'sha1' || $type == null) {
			if (function_exists('sha1')) {
				$return = sha1($string);
				return $return;
			}
			$type = 'sha256';
		}

		if ($type == 'sha256' && function_exists('mhash')) {
			return bin2hex(mhash(MHASH_SHA256, $string));
		}

		if (function_exists('hash')) {
			return hash($type, $string);
		}
		return md5($string);
	}


EDIT:

Разбира се този метод може да го подсигуриш, ако ползваш метода за регистрация / логин, да генерираш и допълнителен салт, който да е на базата на потребителското име или ид + салта който ще въведеш ръчно (този които се зарежда в момента в метода). Това може с една if проверка да стане.
 
Аз за това си използвам няколко email-a..
Един за paypal, един за важни сайтове като web-tourist, fb и друг за съвсем просто дори и за някакви бързи регистрации в free.bg за демота..
Имам и още няколко които също са за неважни неща.
И навсякъде с различни пароли.
Лошото е , че не всички хора мислят как да си защитят данните и то не защото не искат, а защото просто да речем са изкарали 1 компютърен курс (като примерно повечето секретарки) научили са се да работят с някоя програма и с документи но въобще не осъзнават че може да им пострадат данните.
Е то не само секретарките де, за пример го дадох.
Едно 70% сигурно от българското общество ползва пароли a-z, 0-9, a-z+0-9
И едно 10% използват пароли 123456 123456789 asdqwe и т.н. поредни копчета на клавиатурата или едно над друго..
Има доста какво да се говори по тази тема и няма да е зле да се направи точно такъв сайт в който да се обясни на хората как да си защитават личните данни, пароли, email-и и други.
От една страна в днешно време хората правят сайтове за да изкарват пари от тях, а от такъв сайт пари ще се изкарват само от реклами и за това никой не се е навил да го направи.
Но от друга като се замисля, че дори да им обясниш всичко както трябва, повечето хора като видят дълъг текст и ги мързи да го четат.
Е и аз го правя да речем за "правилата" при регистрация в някой сайт, но когато е някакъв важен сайт задължително си прочитам и тях без значение дали са дълги или не.
Та мисълта ми е , че и да направим такъв сайт няма да са много хората които ще четат информацията и ще им бъде полезна.
 
Имах в предвид нещо по опростено, а Яворчо & company не ги зачитам като помощници на хората, а само търсят изява и не се занимават с тези които трябва.. защото все пак те (тези с който по принцип трябва да се занимават) са шефове на шефовете им..

Спирам да спамя и да се отклонявам от темата. ;)
 
Да използваш за Salt потребителско име е просто глупаво и не ефективно (както и всяка друга информация която не може да бъде променена после а си остава статична).

Ако разбираш английски е хубаво да прочетеш това:
http://crackstation.net/hashing-security.htm

Много подробна статия за проблемите на md5 , използването на статична salt като потребителско име (както е дадено в примерите отгоре) както и колко е безмислено използването на 2-3 md5 функций една в друга.

Статията е много хубава и заслужава да бъде прочетена от всеки себеуважаващ се програмист.

След като прочетеш статията може да видиш това:
https://defuse.ca/php-pbkdf2.htm

От автора на първият линк това е код който генерира произволен salt (за всеки потребител!), и го записва в базата ти данни. Script-ът е направен така, че по всяко време може да промениш сложноста на salt-a и броя на hash-ванията през които паролата преминава само с промяната на 1 число. Също така преймуществото му е, че ако потребителя реши да си смени паролата, може да генерираш нов hash с нов salt (а не потребителско име..)
 

Back
Горе