Обучение в PHP - част 12 (Кодиране и хеширане на данни)
Може би се чудите, как възниква въпросът за кодирането на данните при разглеждането на метода за осигуряване на автентичност чрез парола и високата степен на сигурност, която базите данни предлагат при съхраняването на пароли. Базите данни са сигурни, но не може да се разчита само на едно ниво на сигурност. За да разберете това, разгледайте следния пример.

Да предположим, че хакер е успял да влезе в базата ви данни за няколко часа. Този хакер, може да свали целият списък и да използва тази информация по-късно. Можете ли да поискате всеки потребител на сайта да променя паролата си, или да блокирате всички потребители!

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

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

Кодиране на данни

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

Даните се кодират на базата на два компонента - ключ и кодиращ алгоритъм. Ключът трябва да е число или ключова фраза, която да се използва за кодирането на информацията. Следващият компонент е алгоритема за кодиране, който е познат под името кодиращ алгоритъм. Кодиращият алгоритъм е логическа поредица от стъпки, която се използва за конвентиране на оригиналния текст до неразгадаем формат.

Следващият логически въпрос е как се кодират данните ? Процесът на кодиране може да се раздели на следните стъпки:

[list=1]
[*]Текст, напримерно пароли, които трябва да се кодират.
[*]Ключът и алгоритъмът се използват за конвентиране на този текст в случайни битове. В терминологията на кодирането, текстът, който трябва да се кодира, се нарича чист текст. Полученият текс, който сте получили след кодирането се нарича шифриран текст.
[*]В зависимост от нуждите, шифрираният текст след това може да бъде или съхранен ( в базата данни ), или предаден на получателя.
[*]Когато шифрираният текст, трябва да се конвентира обратно до чистия текст, трябва да се използват същите алгоритми и същия ключ, които са били използвани за кодиране на информацията, за да може тя да се декодира.

На базата на броя използвани ключове, техниките на кодиране могат да се разделят на две:


[*]Кодиране с единичен ключ.
[*]Кодиране с публичен ключ.


Кодиране с единичен ключ

При тази техника се използва един и същи ключ за кодиране и декодиране на данните. Като резултат от това, човек който има достъп до кодираните данни, но не и до лкюча, не може да дешифрира съобщението.

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

Освен от ключа, успехът на кодирането с единичен ключ зависи и от кодиращия алгоритъм. Някой от по-извесните алгоритми са:


[*]DES Това е алгоритъм с 56-битов ключ, който разделя данните на блокове с фиксиран размер. Всеки един от тези блокове се кодира независимо от другите. Но кодирането на даден блок, влияе на кодирането на следващия блок.
[*]3DES Това е подобрена и по-сигурна версия на DES, където всеки блок се кодира три пъти, като се използва поне два различни ключа.
[*]IDEA Това е симетричен блоков механизъм за шифриране, който използва 128 битов ключ за кодиране на данните в блокове по 64-бита. Тъй като дължината на ключа в алгоритъма е доста голяма, дори пълното изброяване на ключовете, може да не доведе до резултат. освен това IDEA премахва статистическата зависимост между шифрираният текс и чистият текст. Тези факти правят алгоритъма IDEA един от най-сигурните алгоритми.
[*]RC4 Това е блоков механизъм за шифриране, при който дължината на ключа може да бъде до 2048 бита. Това е бърз, ефективен и сигурен алгоритъм.
[*]CAST-128 Това е блоков механизъм за шифриране, при който се използва ключ с променлива дължина и който генерира 64-битови блокове. Дължината на ключа може да варира от 40 до 128 бита.
[*]АЕС Този алгоритъм успено измести алгоритъма DES и различните му версии. Това е блоков механизъм за шифриране, при който ключът може да е с променлива дължина- 128, 192 и 256 бита. Освен това е много бърз алгоритъм.

Кодирането с единичен ключ е обект на различни атаки, който все още успяват д разкрият оригиналните данни. Тези атаки са:


[*]Атаки с груба сила (Broute Force). При този тип атаки е наличен шифрираният текст. След това се генерират случайни ключове и се прилагат към шифрираният текст, дакато се открие валиден ключ. Този ключ се използва за декодиарне на данните. Успехът на тази атака зависи от дължината на ключа.Колкото по-дълъг е ключа, толкова по-трудно може да се декодира текстът.
[*]Атаки с деференциален анализ на кода. При този тип атаки, вероятния ключ се генерира, като се сравняват двоики от шифрираният текст, за които разликите в чистите ключове са извесни.
[*]Атаки с линеен анализ на кода. При този вид атаки върху битовете от шифрираният текст се прилага операция XOR, която е за битове от чистият текст. След това върху резултат от тези две операции отново се прилага операцията XOR и се получава бит, който е резултат от прилагането на операцията XOR върху някой битове от ключа.


Кодиране с публичен ключ

Това е техника за кодиране, която използва два ключа вместо един. Един от тези ключове се нарича публичен. Другият ключ е секретният ключ, който не е разпространен и е лична собственост на едната страна. Този ключ е познат под името частен ( личен ) ключ. Данните се кодират с помоща на публичен ключ. От друга страна, данните се декодират с частен ключ.

Кодирането с публичен ключ се реализира с помоща на RSA алгоритъма, който носи името си от първите букви на създателите си - Rivest, Shamir и Adelman. Този алгоритъм изисква единичният ключ на комуникацията да знае публичния ключ на другия член. Личният ключ е известен само на потребителя си, но не и за другия участник в комуникацията. В резултат на това, за глобална комуникация са нужни 2n ключа. където n е номерът на потребителя.

Процедурата за кодиране на публичен ключ е следната:


[*]Текст, например пароли, трябва да бъде кодиран.
[*]Изпращача получава публичния ключ на получателя от проверена публично достъпна независима организация.
[*]Подателят кодира данните, използвайки публичен ключ, който е получил.
[*]При получаване на кодирани данни, получателят декодира шифрираният текст, използвайки личният си ключ.

Кодирането с публичен ключ предлага подобрена сигурност. Това е така, защото ключовете не трябва да се предават между подателя и получателя. Всички комуникации използват публичния ключ, а личният клуч остава скрит за любопитните, тъй като не се предава по никакъв начин.

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

PHP поддържа различни механизми за кодиране, като използва популярната библеотека Mycryp. Освен това MySQL също предлага функции, като encode() и decode(), за целите на кодирането

Кодиране в PHP

От предишните уроци се научихте да работите с MySQL, в тази секция ще ви покажа, как можете да използвате кодиращите функции, предоставени от MySQL.

Един от най-лесните методи за кодиране в PHP е използването на функциите encode() и decode(), предоставени от MySQL. Тези функции се използват съответно за кодиране и декодиране на текстови данни, като например пароли.

Синтаксисът на функцията encode() e :

string encode ( string низ, string парола )

Функцията encode() приема два параметъра. Първият е низът, който трябва да се кодира, а вторият параметърът на паролата.

Синтаксисът на функцията decode() e :

string decode ( string низ, string парола )

Функцията decode() също приема два параметъра. Първият аргумент е низът, който трябва да се декодира, като за парола се използва вторият аргумент. Първият низ, трябва да е низ, върнат от функцията encode().

Разгледайте следния код:

// Използване на функцията encode на MySQl за кодиране на пароли
$mingle = "encode('$password', '$password')";
$sqlquery = "INSERT INTO login VALUES ('$id', '$mingle' )";


В горния код се използва функцията encode за кодиране на въведената парола. След това кодиранаа парола се съхранява в базата данни, която която съдържа ID и паролите на потребителите.

Хеширане

Въпреки, че кодирането подсигурява данните ви в значителна степен, хеширането подсигурява максимална сигурност за данните ви, особено в случаите на пароли. При хеширането се генерира хеш стойност за данните, който трябва да се подсигурят. За целта се използва хеш функция. Данните след това се кодират и хеш стойността се съхранява ( или изпраща на получателя ) заедно с кодираните данни. Когато данните трябва да се декодират, освен тях, трябва да се декодира и хеш стойността. Освен това се генерира друга хеш стойност и двете стойности трябва да съвпадат. Ако съвпадат, е сигурно, че данните не са променени.

Разгледайте израза „ A mod B = C“. В този случай стойността С се получава, като се раздели A на B. Ако просто имате стойността C, не можете да направите предложение за оригиналните стойности A и B, защото има безброй много комбинации от числа, които ще дадат същия резултат!

Да разгледаме друг пример. Да предположим, че трябва да хеширате низа „SECRET“. Решавате, че ще използвате съответните ASCII стойности на символите в низа.

S = 83

E = 69

C = 67

R = 82

E = 69

T = 84

-------

454

След събирането се получава числото 454, което е хеш стойността. Ако ви се даде числото 454, не може да се разгадае оригиналния текст от това число, дори и да знаете, че това число се е получило от събирането на ASCII стойностите. Много други низове ще доведат до същата стойност. Например TECRES, CESTER, или всяка друга пермутация на буквите ще даде хеш стойност 454. Виждате, че дори и да промените позицията на буквите, хеш кода ще е същия. За да избегнете това, можете да умножите ASCII стойността на всеки символ с позицията му в низа. В този случай, позициите на всеки символ са:

Позиция : 123456

Текст : SECRET

Сега да умножим позицията на всеки символ в низа с неговата ASCII стойност:

( 83 * 1 ) + ( 69 * 2 ) + ( 67 * 3 ) + ( 82 * 4 ) + ( 69 * 5 ) + ( 84 * 6 )

Сега нека да съберем стойностите, за да получим новата хеш стойност. Ще получите следния резултат:

83

138

201

328

345

504

-----

1599

Сега новата хеш стойност е 1599 и е трудно да се разбере, как е била генерирана!

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

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

За нашич пример за дума SECRET получихме стойността 1599, която може да се получи за много други думи. Много трудно може да се намери алгоритъм, който да генерира уникални стойности – или поне стойности, които много рядко да съвпадат и да не може да се декодират. Един такъв алгоритъм е MD5.

Използване на MD5 хеширане в PHP

Разработен от RSA Data Security, Inc., Message Digest 5 ( MD5 ) е хеширащ алгоритъм, който генерира 128 битова уникална стойност. MD5 също така осигурява, че много трудно може да се генерира еднаква хеш стойност за различни данни. Когато използвате MD5, паролите се съхраняват като хеш стойност.

Във вашите PHP скриптове може да използвате МД5 хеширане чрез функцията md5(). Синтаксиса на функцията е следния :

string md5( string низ )

както можете да видите, функцията приема един аргумент – низ – чиято MD5 хеш стойност искате да намерите.

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


/ Трябва да сте регистриран за да напишете коментар /
От: nepoznatia
16:42 18-08-2010
Хубав е урока, но аз сам си кодирам паролите по много як начин. Направих си скрипт, който слага произволни числа между моите, след което се получава неразгадаем код, които само моя анти-хаш скрипт го разкодира. :)
1