 > Also, what's to stop someone from essential 'brute-forcing' hashes by starting with a and going through all the alpha-numerical symbols for 12 characters or so, and then have a just compare any given password to the compiled list of hashes?

This is called a [rainbow table](_URL_1_). And if you just did something simple like one pass of md5 to make a hash, you could easily find out what the password is from a hash just by [googling it](_URL_2_). This is why you don't just do md5 once. You would use a hashing algorithm (like md5 or better yet SHA256) hundreds of times on the same password. 

You would also use random [salt](_URL_3_) and store it with the hash. A salt is not an encryption key, and having the salt won't allow you to decrypt the hash. It is just some random text you append or prepend (or both) to the original password to make the result more unique. 

What the uniqueness of the salt and multiple passes of the hashing algorithm add are more time to generate all the combinations. This also prevents one rainbow table from being used for every password in your database. You would need to generate the table for each password which takes time. You want to add as much time as possible, such that the time it takes to brute force one password would take years (preferably centuries).

The number of alpha-numerical combinations of 12 length is ~3,226,266,760,000,000,000,000 ((26 + 26 + 10)^12 ). And a even rainbow table that size with just basic one pass md5 and a computer that could calculate a billion md5s a second would take a 100,000+ years to generate the whole table.

So, lets say you have a password. What you do is run it through your hashing algorithm, 1,000,000 times with a random salt appended each time. This process takes a half second to complete on your server. The user doesn't notice since the compute time isn't that long. You store the result, along with the randomly generated salt in your DB. Then the next time the user comes to log in, you take the new password they entered to check and run it though the same process. First you grab the salt from the DB though and use it as the same salt to run the 1,000,000 passes of your hash. If the resulting hash matches, the entered password is correct.

What this has accomplished is two things. First, it slows down the server side validation of a password. A person trying to brute force their way into your server by sending random passwords to be validated would have to wait a half second each time to get an answer. Second, if your database and code was compromised and someone wanted to brute force their on their own super fast machine, they would know your hashing method (1,000,000 sha256 with random salt) and resulting hash, but that would get them nothing really. They'd still need to generate all possible combinations until they matched the password. Most importantly, they'd need to through the whole table out for each password they wanted to crack. As in, if they generated all 8 length combinations to guess the first password, they couldn't use all those generated hashes for the second. 

This whole process will take them a really long to even crack one 8 character length password. Lets say they're machine can do the hashing of one guess in 0.00001 seconds (50,000 times faster than your server). It would take them ~70 years for one password. 

The best thing to do if you are planning to generate your own client login system is to use an already built library for generating and validating hashes. For php, there is the (poorly named) [phPass](_URL_0_).

So is it one-way then? Well, the hash is. But using a hash on a password is not really one-way. Since passwords generally have an upper bound on length (say  < =12 characters for reasonable password use) it makes it such that the space that a hash is mapping probably one have any collisions. Meaning, a generated hash for a password probably won't match another different password (i.e. the hash is unique to the password). But hashing algorithms  aren't specifically designed for use in password encoding. 

They are generally designed for checking data integrity and can take any length string. md5 for example can take a whole harddrive (say 1TB in size) and spit out a 32 length hexadecimal string. It can take an infinite length string and boil it down to a 32 length hexadecimal string. In that scenario, you couldn't take the md5 hash and run through some magic and get the harddrive image. There are millions of strings that would match that hash that are less then a TB is size. So in that sense, the hashing algorithm is "one-way".




 &gt; එසේම, අකුරු 12ක් හෝ ඊට වැඩි සංඛ්‍යාවක් සඳහා වන සියලුම ඇල්ෆා-සංඛ්‍යා සංකේත වලින් ආරම්භ කර, සම්පාදනය කරන ලද හෑෂ් ලැයිස්තුවට ලබා දී ඇති ඕනෑම මුරපදයක් සසඳා බැලීමෙන් යමෙකු අත්‍යවශ්‍ය &#39;බ්රූට්-ෆෝසිං&#39; හෑෂ් වලින් වැලැක්වීමට කුමක් කළ යුතුද? මෙය [රේන්බෝ වගුව](_URL_1_) ලෙස හැඳින්වේ. තවද ඔබ හැෂ් එකක් සෑදීමට md5 හි එක් සාමාර්ථයක් වැනි සරල දෙයක් කළේ නම්, ඔබට [ගූගල් කිරීමෙන්](_URL_2_) හැෂ් එකකින් මුරපදය කුමක්දැයි පහසුවෙන් සොයා ගත හැක. මේ නිසා ඔබ md5 එක වරක් නොකරන්න. ඔබ එකම මුරපදය මත සිය වතාවක් හැෂිං ඇල්ගොරිතමයක් (md5 හෝ වඩා හොඳ SHA256 වැනි) භාවිතා කරනු ඇත. ඔබ අහඹු [ලුණු](_URL_3_) භාවිතා කර එය හෑෂ් සමඟ ගබඩා කරයි. ලුණු යනු සංකේතාංකන යතුරක් නොවන අතර ලුණු තිබීම ඔබට හැෂ් විකේතනය කිරීමට ඉඩ නොදේ. එය ප්‍රතිඵලය වඩාත් අද්විතීය කිරීමට මුල් මුරපදයට ඔබ එකතු කරන හෝ පෙර (හෝ දෙකම) අහඹු පෙළක් පමණි. ලුණුවල සුවිශේෂත්වය සහ හැෂිං ඇල්ගොරිතමයේ බහු වාර ගණන එකතු කිරීම සියලු සංයෝජන උත්පාදනය කිරීමට වැඩි කාලයකි. මෙය ඔබගේ දත්ත ගබඩාවේ සෑම මුරපදයක් සඳහාම එක් දේදුන්න වගුවක් භාවිතා කිරීම වළක්වයි. කාලය ගතවන සෑම මුරපදයක් සඳහාම ඔබට වගුව ජනනය කිරීමට අවශ්‍ය වනු ඇත. ඔබට හැකි තරම් කාලයක් එකතු කිරීමට අවශ්‍ය වේ, එනම් එක් මුරපදයක් තිරිසන් ලෙස බල කිරීමට ගතවන කාලය වසර ගණනාවක් ගතවනු ඇත (වඩාත් ශතවර්ෂ ගණනාවක්). 12 දිග ඇල්ෆා-සංඛ්‍යා සංයෝජන ගණන ~3,226,266,760,000,000,000,000 ((26 + 26 + 10)^12 ) වේ. එම්ඩී 5 මූලික එක් සාමාර්ථයක් සහිත ප්‍රමාණයේ ඉරට්ටේ රේන්බෝ මේසයක් සහ තත්පරයකට බිලියන එම්ඩී 5 ගණන් කළ හැකි පරිගණකයක් මුළු වගුවම ජනනය කිරීමට වසර 100,000+ ගත වනු ඇත. ඉතින්, ඔබට මුරපදයක් ඇතැයි කියමු. ඔබ කරන්නේ එය ඔබගේ හැෂිං ඇල්ගොරිතම හරහා 1,000,000 වාරයක් අහඹු ලුණු එකතු කර ධාවනය කිරීමයි. මෙම ක්‍රියාවලිය ඔබගේ සේවාදායකයේ සම්පූර්ණ වීමට තත්පර භාගයක් ගතවේ. ගණනය කිරීමේ කාලය එතරම් දිගු නොවන බැවින් පරිශීලකයා නොදකියි. ඔබ ඔබේ DB හි අහඹු ලෙස ජනනය කරන ලද ලුණු සමඟ ප්‍රතිඵලය ගබඩා කරයි. ඊළඟ වතාවේ පරිශීලකයා ලොග් වීමට පැමිණෙන විට, ඔබ පරීක්ෂා කිරීමට ඔවුන් ඇතුළත් කළ නව මුරපදය ගෙන එය එකම ක්‍රියාවලියක් වුවද ක්‍රියාත්මක කරන්න. මුලින්ම ඔබ DB එකෙන් ලුණු ලබාගෙන ඔබේ හැෂ් 1,000,000 පාස් ධාවනය කිරීමට එම ලුණු ලෙසම භාවිතා කරන්න. ප්‍රතිඵලයක් ලෙස හැෂ් එක ගැළපේ නම්, ඇතුළත් කළ මුරපදය නිවැරදි වේ. මෙයින් ඉටු වී ඇත්තේ කාරණා දෙකකි. පළමුව, එය මුරපදයක සේවාදායක පැත්ත වලංගු කිරීම මන්දගාමී කරයි. වලංගු කිරීමට අහඹු මුරපද යැවීමෙන් ඔබේ සේවාදායකයට බලහත්කාරයෙන් ඇතුල් වීමට උත්සාහ කරන පුද්ගලයෙකුට පිළිතුරක් ලබා ගැනීමට සෑම අවස්ථාවකම තත්පර භාගයක් බලා සිටීමට සිදු වේ. දෙවනුව, ඔබේ දත්ත සමුදාය සහ කේතය සම්මුතියකට ලක් වී ඇත්නම් සහ යමෙකුට ඔවුන්ගේම සුපිරි වේගවත් යන්ත්‍රය මත බලහත්කාරයෙන් බල කිරීමට අවශ්‍ය නම්, ඔවුන් ඔබේ හැෂිං ක්‍රමය (අහඹු ලුණු සහිත 1,000,000 sha256) සහ එහි ප්‍රතිඵලය වන හෑෂ් දැන ගනු ඇත, නමුත් එයින් ඔවුන්ට කිසිවක් නොලැබෙනු ඇත. මුරපදයට ගැළපෙන තෙක් ඔවුන්ට හැකි සියලු සංයෝජන උත්පාදනය කිරීමට අවශ්‍ය වේ. වැදගත්ම දෙය නම්, ඔවුන්ට කැඩීමට අවශ්‍ය සෑම මුරපදයක් සඳහාම මුළු වගුව හරහා යාමට අවශ්‍ය වීමයි. ඔවුන් පළමු මුරපදය අනුමාන කිරීමට දිග සංයෝජන 8ම ජනනය කළේ නම්, ඔවුන්ට එම උත්පාදනය කළ හැෂ් සියල්ල දෙවැන්න සඳහා භාවිත කළ නොහැක. මෙම සම්පූර්ණ ක්‍රියාවලිය ඔවුන්ට එක් අක්ෂර 8ක දිග මුරපදයක් පවා බිඳ දැමීමට බොහෝ කාලයක් ගතවනු ඇත. තත්පර 0.00001 කින් (ඔබේ සේවාදායකයට වඩා 50,000 ගුණයකින් වේගවත්) එක් අනුමානයක් හැෂ් කිරීම යන්ත්‍රයට හැකි යැයි කියමු. එක් මුරපදයක් සඳහා ඔවුන්ට ~70 වසරක් ගතවනු ඇත. ඔබ ඔබේම සේවාදායක පිවිසුම් පද්ධතියක් උත්පාදනය කිරීමට අදහස් කරන්නේ නම් කළ යුතු හොඳම දෙය නම් හැෂ් ජනනය කිරීම සහ වලංගු කිරීම සඳහා දැනටමත් ගොඩනගා ඇති පුස්තකාලයක් භාවිතා කිරීමයි. php සඳහා, (දුර්වල නම්) [phPass](_URL_0_) ඇත. එහෙනම් ඒක එක පැත්තක්ද? හොඳයි, හැෂ් තමයි. නමුත් මුරපදයක් මත හැෂ් භාවිතා කිරීම ඇත්ත වශයෙන්ම එක් මාර්ගයක් නොවේ. මුරපද සාමාන්‍යයෙන් දිග මත ඉහළ සීමාවක් ඇති බැවින් (සාධාරණ මුරපද භාවිතය සඳහා අක්ෂර &lt; =12 යැයි කියන්න) එය හැෂ් සිතියම්ගත කරන ඉඩෙහි යම් ගැටුමක් ඇති විය හැක. අර්ථය, මුරපදයක් සඳහා ජනනය කරන ලද හැෂ් වෙනත් වෙනත් මුරපදයක් නොගැලපේ (එනම් හැෂ් මුරපදයට අනන්‍ය වේ). නමුත් හැෂිං ඇල්ගොරිතම මුරපද කේතනය කිරීමේදී භාවිතා කිරීම සඳහා විශේෂයෙන් නිර්මාණය කර නොමැත. ඒවා සාමාන්‍යයෙන් නිර්මාණය කර ඇත්තේ දත්ත අඛණ්ඩතාව පරීක්ෂා කිරීම සඳහා වන අතර ඕනෑම දිග නූලක් ගත හැක. උදාහරණයක් ලෙස md5 හට සම්පූර්ණ දෘඪ තැටියක් ගත හැක (ප්‍රමාණයෙන් 1TB කියන්න) සහ 32 දිග ෂඩාස්‍ර තන්තුවක් පිට කළ හැක. එයට අනන්ත දිග නූලක් ගෙන එය 32 දිග ෂඩාස්‍ර නූලකට තම්බා ගත හැක. එම අවස්ථාවේ දී, ඔබට md5 හෑෂ් ගෙන කිසියම් මැජික් එකක් හරහා ගොස් දෘඪ තැටි රූපය ලබා ගැනීමට නොහැකි විය. TB ප්‍රමාණයට වඩා අඩු එම හැෂ් සමඟ ගැළපෙන නූල් මිලියන ගණනක් ඇත. එබැවින් එම අර්ථයෙන්, හැෂිං ඇල්ගොරිතම &quot;එක් මාර්ගයක්&quot; වේ.



