C, PHP, VB, .NET

Дневникът на Филип Петров


* Hash алгоритми за криптиране

Публикувано на 21 ноември 2008 в раздел ОСУП.

След като обяснихме ползата от криптиране на базата данни остана въпроса как е най-подходящо да го направим. Стандартно и най-често използвани са hash алгоритмите. Това са функции, които трансформират подаден текст само в едната посока (тоест веднъж криптиран не съществува възможност за съставяне на обратен алгоритъм). Най-важната черта за един hash алгоритъм е резултатът от него да изглежда колкото се може повече произволен (тоест да не можем да правим заключение за евентуалният вид на оригиналният текст по вида на криптирания вариант). С други думи двата символни низа „общината отново вдигна данък смет“ и „общината отново вдигна данъка смет“ би трябвало да дадат визуално напълно различни резултати след криптиране.

В интернет приложенията широко се използват два много популярни hash алгоритъма – sha1 и md5. Следният пример демонстрира тяхното действие:

<html>
<head>
</head>
<body>
<?php
	$originalText = "Obshtinata otnovo vdigna danak smet";
	echo "Original text: ".$originalText;
	echo "<br>SHA1 (160bit) hash: ";
	echo sha1($originalText);
	echo "<br>MD5 (128bit) hash: ";
	echo md5($originalText);

	$originalText = "Obshtinata otnovo vdigna danaka smet";
	echo "<br><br>Original text: ".$originalText;
	echo "<br>SHA1 (160bit) hash: ";
	echo sha1($originalText);
	echo "<br>MD5 (128bit) hash: ";
	echo md5($originalText);
?>
</body>
</html>

Резултатът след изпълнението на този скрипт ще бъде следния:

	Original text: Obshtinata otnovo vdigna danak smet
	SHA1 (160bit) hash: 56b5f0e231d56ab1b659e37418b56042283e12be
	MD5 (128bit) hash: 16e2021a032e1937935e3118a9efbdf0

	Original text: Obshtinata otnovo vdigna danaka smet
	SHA1 (160bit) hash: a96ddc612e80db0274b40a9b6da8a30396133364
	MD5 (128bit) hash: 077d6a15d24fa1647b5d6b4f9bff1844

Виждате, че тези два алгоритъма се справят достатъчно добре със задачата (*). Начините да „разкодирате“ криптирана парола е използването на т.нар. rainbow таблици или използването на brute force атака.

Rainbow таблиците са бази от данни с изключително голямо количество двойки от тип „оригинален символен низ“ – „криптиран символен низ“. Когато пуснете заявка в тази база данни с криптирания низ ако се намери съвпадение ще получите оригиналния текст. Трябва да знаете, че съществуват изключително големи rainbow таблици. Например в gdataonline.com има над 1,133,759,239 записа на MD5 хешове на всякакви комбинации от думи и цифри на различни езици. Затова спазването на строги правила относно сложността на паролите е от голямо значение.

Естествено може да се досетите, че генерирането на rainbow таблица като споменатата по-горе ще изисква огромно количество дисково пространство. За да се редуцира този размер се използва техниката за използване на „редуцираща функция“ (reduction function), която ни позволява да се намали обема на данните, но за сметка на това да се увелици процесорното време отделено за претърсване на таблицата. За повече информация вижте статията в Уикипедия.

Brute Force атаките влизат в употреба тогава, когато rainbow таблиците не дават резултат. На практика принципа е почти същия – обикновено се избират някакви ключови думи и започват да се пробват всякакъв вид комбинации между тях с числа и други символи. Търсенето по този начин е многократно по-бавно от използването на таблици. Въпреки това става дума за генериране на хиляди хешове в секунда и се оказва достатъчно ефективно при разбиване на конкретни акаунти.

Вървейки по този принцип става ясно едно – рано или късно ако някой е достатъчно настоятелен и има достатъчно ресурси, то той ще „разбие“ нашата хеширана парола (ще намери нея или друг ключ, който дава същия хеш – колизия). Поради тази причина е нужно да помислим за някакви допълнителни методи, които да спестят бъдещи главоболия:

1. Многократно криптиране: това е често използвана практика – например двоен MD5, троен MD5 и т.н. По този начин „криптираме криптираното“ и с това увеличаваме времето, необходимо за разбиване на паролата. Слабата страна на този метод, е че времето отделено за обработка на данните от страна на нашия сървър нараства с толкова пъти, колкото криптираме символните низове. За щастие допълнителното натоварване на сървъра е мното по-малко от това, което ще е нужно на човека, който „разбива“ паролата (необходимото време на сървъра расте линейно). Затова (ако се използват „бързи хеш алгоритми“, каквито впрочем са стандартните) не е неадекватно да се направи многократно криптиране от стотици, дори хиляди пъти.

2. Комбинирано криптиране: това е например когато криптираме текст с MD5 и след това криптираме създадения hash повторно с SHA1. Комбинацията от алгоритми е всевъзможна. Ефектът е допълнително подобрение на предишната точка.

3. Използване на „salt“: много силна техника, която помага изключително много срещу rainbow таблици. Вместо да записваме директно криптираният код на паролата, ние долепяме произволен (и задължително сложен и дълъг) символен низ към нея, след което я криптираме и записваме. Така складираната парола в базата данни ще бъде достатъчно сложна, за да устои на каквато и да е rainbow таблица.

Първите два метода не решават напълно проблема с brute force атаките. Ако атакуващият просто регистрира собствен акаунт в системата, то той лесно ще може да разбере каква комбинация от алгоритми сте използвали, след което да си конструира нова собствена rainbow таблица. Може да се приеме, че в комбинация с правилно използване на третия метод ще имаме значително добър резултат и може да се каже, че данните ще са защитени.

Използването на по-нов алгоритъм за криптиране допълнително подобрява нещата. Вече съществуват подобрени варианти на SHA – SHA-224, SHA-256, SHA-384, and SHA-512 (познати също под общо име като SHA2). Стандартът SHA3 е в процес на разработка. Съществуват и редица популярни алгоритми като Ripemd, Whirlpool, Haval, Tiger, и т.н. В никакъв случай не използвайте стари и доказано компрометирани hash алгоритми, като например MD4.

(*) Всъщност дори често използваните md5 и sha1 от няколко години насам се считат за НЕСИГУРНИ алгоритми. Препоръчително е да използвате sha256 или ripemd160 (популярни алгоритми, които се поддържат и от OpenSSL). В PHP използвайте функцията hash:

hash(‘ripemd256’, ‘password’);
hash(‘sha256’, ‘password’);

Базите данни MySQL поддържат sha256 чрез функцията SHA2(‘password’,256).

 



9 коментара


  1. Bakudan каза:

    Имам един въпрос – сайт предлага се автоматично генериране на парола, която е от случайни символи. Добре, криптира се, и това добре. Само, че обикновенно това, което се генерира не е с различна дължина за различните потребители. И тук идва момента, който ми се струва интересен – добавянето на salt, няма да увеличи сигурността особенно. Познати смятат, че подобен тип абсолютно случайни пароли вършат работа. На мен ми се струва че този метод е ненадеждан.
    Примерно написвам си програмка за генериране на случайни низове, задавам параметри за варираща дължина, за използвани знаци, за криптиране SHA1/MD5, и си правя една хубава табличка. Теоретично така не се ли увеличава шанса за пробив? А и при такава ситуация, моята намаса епочти нулева.

  2. Здравей,

    Стига алгоритъмът за генериране на случайни низове да е добър (тоест нормално разпределени резултати без много повторения на символи), то не е особен проблем. Естествено много добре си забелязал слабостта със статична дължина на низа – ясно е, че това улеснява евентуален анализ на изтеглена база от закодирани пароли.

    Колкото до salt – прочети следната статия:

    Добавяне на Salt към паролите

    Според мен вторият вид salt не е безполезен, дори при споменатите случайни пароли.

  3. Борислава:

    1. Можеш ли да пишеш на кирилица?;

    2. Регистрирай си e-mail с тире ако е свободен;

    3. Ако 2. не става – пиши на поддръжката на Мтел.

    Въпросът ти няма нищо общо с темата на статията!

  4. борислава каза:

    nqkoi moje l ida mi pomogne imam profil v sms.mtel.net i sam si zabravila parolata sled tova pisha si emaila za da moje da mi q prati i se okazva 4e pri registriraneto sam napisala vmesto dolna 4erta tire i sega vemoga da si vlqza v profila ami trqbvat telefonite ot tam

  5. nadq yordanova каза:

    Molq decriptiraite mi tova:
    0deaf7cd13a645abdd75307e9c4e9007
    ako nqkoi moje da pomogne ste buda blagodarna!
    kitkat1@abv.bg

  6. nadq yordanova каза:

    blagodarq vse pak ako moje da mi dadete savet kak da otkriq re6enieto …..molq

  7. Гаджев каза:

    Ако вместо да се, използват rainbow таблици за да се открие паролата, директно се изпращат низове наподобяващи низовете от MD5 или SHA генерирани посредством brute force, ще се заобиколи смисъла от криптирането. Тоест, имаме краен брой възможности за изходни комбинации от криптиращите алгоритми, които могат да бъдат тествани и без да се установи паролата, все пак да се „пробие“ защитата. Може би по-дълги комбинации и проверка на броя некоректни опита за достъп, би бил добро допълнение на тези алгоритми в практиката.

  8. Ако те разбрах вярно, то отговорът ми е НЕ, това няма да заобиколи нищо. Каквито и низове да се изпращат те минават през hash алгоритъма и той не може да се заобиколи. В частност дори да се изпрати като парола hash код, то се получава двойно хеширане. Атака чрез изпращане на hash кодове вместо пароли е силно безсмислена.

Добави коментар

Адресът на електронната поща няма да се публикува


*