Misplaced Pages

Rainbow table: Difference between revisions

Article snapshot taken from Wikipedia with creative commons attribution-sharealike license. Give it a read and then ask your questions in the chat. We can research this topic together.
Browse history interactively← Previous editContent deleted Content addedVisualWikitext
Revision as of 19:00, 11 January 2021 edit103.242.23.191 (talk) https://www.facebook.com/eiramoni.eiramoni.7Tags: Visual edit Mobile edit Mobile web edit← Previous edit Latest revision as of 12:15, 28 November 2024 edit undoFavonian (talk | contribs)Autopatrolled, Administrators287,439 editsm Reverted edit by 2402:8100:2048:4FDF:0:0:BCC6:7773 (talk) to last version by ChipmunkdavisTag: Rollback 
(275 intermediate revisions by more than 100 users not shown)
Line 1: Line 1:
{{short description|Precomputed table for reversing cryptographic hash functions}} {{Short description|Password cracking dataset}}
A '''rainbow table''' is a ] ] for caching the outputs of a ], usually for cracking password hashes. Passwords are typically stored not in plain text form, but as hash values. If such a database of hashed passwords falls into the hands of attackers, they can use a precomputed rainbow table to recover the plaintext passwords. A common defense against this attack is to compute the hashes using a ] that adds a "]" to each password before hashing it, with different passwords receiving different salts, which are stored in plain text along with the hash.
{{More footnotes|date=March 2009}}


<span lang="en" dir="ltr">A</span> '''rainbow table''' is a ] ] for caching the output of ]s, usually for cracking password hashes. Tables are usually used in recovering a ] (or credit card numbers, etc.) up to a certain length consisting of a limited set of characters. It is a practical example of a ], using less computer processing time and more storage than a ] which calculates a hash on every attempt, but more processing time and less storage than a simple ] with one entry per hash. Use of a ] that employs a ] makes this Rainbow tables are a practical example of a ]: they use less computer processing time and more storage than a ] which calculates a hash on every attempt, but more processing time and less storage than a simple table that stores the hash of every possible password.
attack infeasible.


Rainbow tables were invented by Philippe Oechslin<ref name="ophpaper"/> as an application of an earlier, simpler algorithm by ].<ref name="Hellman1980">{{cite journal|last1=Hellman|first1=M.|title=A cryptanalytic time-memory trade-off|journal=IEEE Transactions on Information Theory|volume=26|issue=4|year=1980|pages=401–406|issn=0018-9448|doi=10.1109/TIT.1980.1056220|url=http://www-ee.stanford.edu/~hellman/publications/36.pdf|citeseerx= 10.1.1.120.2463}}</ref> Rainbow tables were invented by Philippe Oechslin<ref name="ophpaper"/> as an application of an earlier, simpler algorithm by ].<ref name="Hellman1980">{{cite journal|last1=Hellman|first1=M.|
title=A cryptanalytic time-memory trade-off|journal=IEEE Transactions on Information Theory|volume=26|issue=4|year=1980|pages=401–406|issn=0018-9448|doi=10.1109/TIT.1980.1056220|url=http://www-ee.stanford.edu/~hellman/publications/36.pdf|citeseerx= 10.1.1.120.2463|s2cid=552536 }}</ref>


==Background== ==Background==
Any computer system that requires password ] must contain a database of passwords, either in ] or hashed in some form; therefore various techniques of ] exist. Because the tables are vulnerable to theft, storing the plaintext password is dangerous. Most databases, therefore, store a ] of a user's password in the database. In such a system, no one &ndash; including the authentication system &ndash; can determine what a user's password is by merely looking at the value stored in the database. Instead, when a user enters a password for authentication, the system computes the hash value for the provided password, and that hash value is compared to the stored hash for that user. Authentication is successful if the two hashes match. For user ], passwords are stored either as ] or ]. Since passwords stored as plaintext are easily stolen if database access is compromised, databases typically store hashes instead. Thus, no one &ndash; including the authentication system &ndash; can learn a password merely by looking at the value stored in the database.

After gathering a password hash, using the said hash as a password would fail since the authentication system would hash it a second time. To learn a user's password, a password that produces the same hashed value must be found, usually through a brute-force or dictionary attack.
When a user enters a password for authentication, a hash is computed for it and then compared to the stored hash for that user. Authentication fails if the two hashes do not match; moreover, authentication would equally fail if a hashed value were entered as a password, since the authentication system would hash it a second time.
Rainbow tables are one type of tool that have been developed to derive a password by looking only at a hashed value.

Rainbow tables are not always needed as there are more straightforward methods of plaintext recovery available. ]s and ]s are the most straightforward methods available. However, these are not adequate for systems that use long passwords because of the difficulty of storing all the options available and searching through such an extensive database to perform a reverse lookup of a hash.
To learn a password from a hash is to find a string which, when input into the hash function, creates that same hash. This is the same as ] the hash function.
To address this issue of scale, reverse lookup tables were generated that stored only a smaller selection of hashes that when reversed could make long chains of passwords. Although the reverse lookup of a hash in a chained table takes more computational time, the lookup table itself can be much smaller, so hashes of longer passwords can be stored. Rainbow tables are a refinement of this chaining technique and provide a solution to a problem called chain collisions.

Though ] (e.g. ]) may be used to try to invert a hash function, they can become infeasible when the set of possible passwords is large enough. An alternative to brute-force is to use ] tables. Rainbow tables are a special kind of such table that overcome certain ].

==Etymology== ==Etymology==
] ]
The term, "Rainbow Tables," was first used in Dr. Oechslin's initial paper. The term refers to the way different reduction functions are used to increase the success rate of the attack. The original method by Hellman uses many small tables with a different reduction function each. Rainbow tables are much bigger and use a different reduction function in each column. When colors are used to represent the reduction functions, a rainbow appears in the rainbow table. The term ''rainbow tables'' was first used in Oechslin's initial paper. The term refers to the way different reduction functions are used to increase the success rate of the attack. The original method by Hellman uses many small tables with a different reduction function each. Rainbow tables are much bigger and use a different reduction function in each column. When colors are used to represent the reduction functions, a rainbow appears in the rainbow table.
Figure 2 of Dr. Oechslin's paper contains a black-and-white graphic that illustrates how these sections are related. For his presentation at the Crypto 2003 conference, Dr. Oechslin added color to the graphic in order to make the rainbow association more clear. The enhanced graphic that was presented at the conference is shown to the right. Figure 2 of Oechslin's paper contains a black-and-white graphic that illustrates how these sections are related. For his presentation at the Crypto 2003 conference, Oechslin added color to the graphic in order to make the rainbow association more clear. The enhanced graphic that was presented at the conference is shown in the illustration.

==Precomputed hash chains== ==Precomputed hash chains==
{{For|hash chains other than what is mentioned here|hash chain}} {{For|hash chains other than what is mentioned here|hash chain}}
Suppose we have a password hash function H and a finite set of passwords P. The goal is to precompute a data structure that, given any output ''h'' of the hash function, can either locate an element ''p'' in P such that H(''p'') = ''h'', or determine that there is no such ''p'' in P. The simplest way to do this is compute H(''p'') for all ''p'' in P, but then storing the table requires ](|P|''n'') bits of space, where |P| is the size of the set P and ''n'' is the size of an output of H, which is prohibitive for large |P|. Given a password hash function H and a finite set of passwords P, the goal is to precompute a data structure that, given any output ''h'' of the hash function, can either locate an element ''p'' in P such that H(''p'') = ''h'', or determine that there is no such ''p'' in P. The simplest way to do this is compute H(''p'') for all ''p'' in P, but then storing the table requires ](|P|''n'') bits of space, where |P| is the size of the set P and ''n'' is the size of an output of H, which is prohibitive for large |P|. Hash chains are a technique for decreasing this space requirement. The idea is to define a ''reduction function'' R that maps hash values back into values in P. Note, however, that the reduction function is not actually an inverse of the hash function, but rather a different function with a swapped ] and ] of the hash function. By alternating the hash function with the reduction function, ''chains'' of alternating passwords and hash values are formed. For example, if P were the set of lowercase alphabetic 6-character passwords, and hash values were 32 bits long, a chain might look like this:
Hash chains are a technique for decreasing this space requirement. The idea is to define a ''reduction function'' R that maps hash values back into values in P. Note, however, that the reduction function is not actually an inverse of the hash function, but rather a different function with a swapped ] and ] of the hash function. By alternating the hash function with the reduction function, ''chains'' of alternating passwords and hash values are formed. For example, if P were the set of lowercase alphabetic 6-character passwords, and hash values were 32 bits long, a chain might look like this:
:<math>{\color{Red}\mathtt{aaaaaa}}\,\xrightarrow{}\,\mathtt{281DAF40}\,\xrightarrow{}\,\mathtt{sgfnyd}\,\xrightarrow{}\,\mathtt{920ECF10}\,\xrightarrow{}\,{\color{Violet}\mathtt{kiebgt}}</math> :<math>{\color{Red}\mathtt{aaaaaa}}\,\xrightarrow{}\,\mathtt{281DAF40}\,\xrightarrow{}\,\mathtt{sgfnyd}\,\xrightarrow{}\,\mathtt{920ECF10}\,\xrightarrow{}\,{\color{Violet}\mathtt{kiebgt}}</math>


Line 27: Line 30:
To generate the table, we choose a random set of ''initial passwords'' from P, compute chains of some fixed length ''k'' for each one, and store ''only'' the first and last password in each chain. The first password is called the ''starting point'' and the last one is called the ''endpoint''. In the example chain above, "aaaaaa" would be the starting point and "kiebgt" would be the endpoint, and none of the other passwords (or the hash values) would be stored. To generate the table, we choose a random set of ''initial passwords'' from P, compute chains of some fixed length ''k'' for each one, and store ''only'' the first and last password in each chain. The first password is called the ''starting point'' and the last one is called the ''endpoint''. In the example chain above, "aaaaaa" would be the starting point and "kiebgt" would be the endpoint, and none of the other passwords (or the hash values) would be stored.


Now, given a hash value ''h'' that we want to invert (find the corresponding password for), compute a chain starting with ''h'' by applying R, then H, then R, and so on. If at any point we observe a value matching one of the endpoints in the table, we get the corresponding starting point and use it to recreate the chain. There's a good chance that this chain will contain the value ''h'', and if so, the immediately preceding value in the chain is the password ''p'' that we seek. Now, given a hash value ''h'' to invert (find the corresponding password for), compute a chain starting with ''h'' by applying R, then H, then R, and so on. If at any point a value matches one of the endpoints in the table, the corresponding starting point allows to recreate the complete chain. There's a high chance that this chain will contain the value ''h'', and if so, the immediately preceding value in the chain is the password ''p'' that we seek.


For example, if we're given the hash {{mono|920ECF10}}, we would compute its chain by first applying R: For example, given the hash {{mono|920ECF10}}, its chain can be computed by first applying R:


:<math>\mathtt{920ECF10}\,\xrightarrow{}\,{\color{Violet}\mathtt{kiebgt}}</math> :<math>\mathtt{920ECF10}\,\xrightarrow{}\,{\color{Violet}\mathtt{kiebgt}}</math>


Since "{{mono|kiebgt}}" is one of the endpoints in our table, we then take the corresponding starting password "{{mono|aaaaaa}}" and follow its chain until 920ECF10 is reached: Since "{{mono|kiebgt}}" is one of the endpoints in our table, the corresponding starting password "{{mono|aaaaaa}}" allows to follow its chain until {{mono|920ECF10}} is reached:


:<math>{\color{Red}\mathtt{aaaaaa}}\,\xrightarrow{}\,\mathtt{281DAF40}\,\xrightarrow{}\,\mathtt{sgfnyd}\,\xrightarrow{}\,\mathtt{920ECF10}</math> :<math>{\color{Red}\mathtt{aaaaaa}}\,\xrightarrow{}\,\mathtt{281DAF40}\,\xrightarrow{}\,\mathtt{sgfnyd}\,\xrightarrow{}\,\mathtt{920ECF10}</math>
Line 39: Line 42:
Thus, the password is "{{mono|sgfnyd}}" (or a different password that has the same hash value). Thus, the password is "{{mono|sgfnyd}}" (or a different password that has the same hash value).


Note however that this chain does not ''always'' contain the hash value ''h''; it may so happen that the chain starting at ''h'' merges with a chain having a different starting point. For example, we may be given a hash value FB107E70, and when we follow its chain, we get kiebgt: Note however that this chain does not ''always'' contain the hash value ''h''; it may so happen that the chain starting at ''h'' merges with a chain having a different starting point. For example, the chain of hash value {{mono|FB107E70}}, also leads to {{mono|kiebgt}}:


:<math>\mathtt{FB107E70}\,\xrightarrow{}\,\mathtt{bvtdll}\,\xrightarrow{}\,\mathtt{0EE80890}\,\xrightarrow{}\,{\color{Violet}\mathtt{kiebgt}}</math> :<math>\mathtt{FB107E70}\,\xrightarrow{}\,\mathtt{bvtdll}\,\xrightarrow{}\,\mathtt{0EE80890}\,\xrightarrow{}\,{\color{Violet}\mathtt{kiebgt}}</math>


But {{mono|FB107E70}} is not in the chain starting at "aaaaaa". This is called a ''false alarm''. In this case, we ignore the match and continue to extend the chain of ''h'' looking for another match. If the chain of ''h'' gets extended to length ''k'' with no good matches, then the password was never produced in any of the chains. The chain generated by the corresponding starting password "{{mono|aaaaaa}}" is then followed until {{mono|FB107E70}} is reached. The search will end without reaching {{mono|FB107E70}} because this value is not contained in the chain. This is called a ''false alarm''. In this case, the match is ignored and the chain of ''h'' is extended looking for another match. If the chain of ''h'' gets extended to length ''k'' with no good matches, then the password was never produced in any of the chains.


The table content does not depend on the hash value to be inverted. It is created once and then repeatedly used for the lookups unmodified. Increasing the length of the chain decreases the size of the table. It also increases the time required to perform lookups, and this is the time-memory trade-off of the rainbow table. In a simple case of one-item chains, the lookup is very fast, but the table is very big. Once chains get longer, the lookup slows, but the table size goes down. The table content does not depend on the hash value to be inverted. It is created once and then repeatedly used for the lookups unmodified. Increasing the length of the chain decreases the size of the table. However, it also increases the time required to perform lookups, and this is the time-memory trade-off of the rainbow table. In a simple case of one-item chains, the lookup is very fast, but the table is very big. Once chains get longer, the lookup slows, but the table size goes down.


Simple hash chains have several flaws. Most serious if at any point two chains ''collide'' (produce the same value), they will merge and consequently the table will not cover as many passwords despite having paid the same computational cost to generate. Because previous chains are not stored in their entirety, this is impossible to detect efficiently. For example, if the third value in chain 3 matches the second value in chain 7, the two chains will cover almost the same sequence of values, but their final values will not be the same. The hash function H is unlikely to produce collisions as it is usually considered an important security feature not to do so, but the reduction function R, because of its need to correctly cover the likely plaintexts, can not be collision resistant. Simple hash chains have several flaws. Most serious if at any point two chains ''collide'' (produce the same value), they will merge and consequently the table will not cover as many passwords despite having paid the same computational cost to generate. Because previous chains are not stored in their entirety, this is impossible to detect efficiently. For example, if the third value in chain 3 matches the second value in chain 7, the two chains will cover almost the same sequence of values, but their final values will not be the same. The hash function H is unlikely to produce collisions as it is usually considered an important security feature not to do so, but the reduction function R, because of its need to correctly cover the likely plaintexts, cannot be ].


Other difficulties result from the importance of choosing the correct function for R. Picking R to be the identity is little better than a brute force approach. Only when the attacker has a good idea of what the likely plaintexts will be they can choose a function R that makes sure time and space are only used for likely plaintexts, not the entire space of possible passwords. In effect R shepherds the results of prior hash calculations back to likely plaintexts but this benefit comes with the drawback that R likely won't produce every possible plaintext in the class the attacker wishes to check denying certainty to the attacker that no passwords came from their chosen class. Also it can be difficult to design the function R to match the expected distribution of plaintexts.<ref name="Hellman1980" /> Other difficulties result from the importance of choosing the correct function for R. Picking R to be the identity is little better than a brute force approach. Only when the attacker has a good idea of likely plaintexts will they be able to choose a function R that makes sure time and space are only used for likely plaintexts, not the entire space of possible passwords. In effect R shepherds the results of prior hash calculations back to likely plaintexts but this benefit comes with the drawback that R likely won't produce every possible plaintext in the class the attacker wishes to check denying certainty to the attacker that no passwords came from their chosen class. Also it can be difficult to design the function R to match the expected distribution of plaintexts.<ref name="Hellman1980" />


== Rainbow tables == == Rainbow tables ==
Rainbow tables effectively solve the problem of collisions with ordinary hash chains by replacing the single reduction function R with a sequence of related reduction functions R<sub>1</sub> through R<sub>''k''</sub>. In this way, for two chains to collide and merge they must hit the same value ''on the same iteration'': consequently, the final values in these chain will be identical. A final postprocessing pass can sort the chains in the table and remove any "duplicate" chains that have the same final values as other chains. New chains are then generated to fill out the table. These chains are not ''collision-free'' (they may overlap briefly) but they will not merge, drastically reducing the overall number of collisions.{{citation needed|date=July 2013}} Rainbow tables effectively solve the problem of ]s with ordinary hash chains by replacing the single reduction function R with a sequence of related reduction functions R<sub>1</sub> through R<sub>''k''</sub>. In this way, for two chains to collide and merge they must hit the same value ''on the same iteration'': consequently, the final values in these chain will be identical. A final postprocessing pass can sort the chains in the table and remove any "duplicate" chains that have the same final values as other chains. New chains are then generated to fill out the table. These chains are not ''collision-free'' (they may overlap briefly) but they will not merge, drastically reducing the overall number of collisions.{{citation needed|date=July 2013}}


Using sequences of reduction functions changes how lookup is done: because the hash value of interest may be found at any location in the chain, it's necessary to generate ''k'' different chains. The first chain assumes the hash value is in the last hash position and just applies R<sub>''k''</sub>; the next chain assumes the hash value is in the second-to-last hash position and applies R<sub>''k''−1</sub>, then H, then R<sub>''k''</sub>; and so on until the last chain, which applies all the reduction functions, alternating with H. This creates a new way of producing a false alarm: if we "guess" the position of the hash value wrong, we may needlessly evaluate a chain. Using sequences of reduction functions changes how lookup is done: because the hash value of interest may be found at any location in the chain, it's necessary to generate ''k'' different chains. The first chain assumes the hash value is in the last hash position and just applies R<sub>''k''</sub>; the next chain assumes the hash value is in the second-to-last hash position and applies R<sub>''k''−1</sub>, then H, then R<sub>''k''</sub>; and so on until the last chain, which applies all the reduction functions, alternating with H. This creates a new way of producing a false alarm: an incorrect "guess" of the position of the hash value may needlessly evaluate a chain.


Although rainbow tables have to follow more chains, they make up for this by having fewer tables: simple hash chain tables cannot grow beyond a certain size without rapidly becoming inefficient due to merging chains; to deal with this, they maintain multiple tables, and each lookup must search through each table. Rainbow tables can achieve similar performance with tables that are ''k'' times larger, allowing them to perform a factor of ''k'' fewer lookups. Although rainbow tables have to follow more chains, they make up for this by having fewer tables: simple hash chain tables cannot grow beyond a certain size without rapidly becoming inefficient due to merging chains; to deal with this, they maintain multiple tables, and each lookup must search through each table. Rainbow tables can achieve similar performance with tables that are ''k'' times larger, allowing them to perform a factor of ''k'' fewer lookups.
Line 63: Line 66:
#:Note: If this new test fails again, one continues with 3 reductions, 4 reductions, etc. until the password is found. If no chain contains the password, then the attack has failed. #:Note: If this new test fails again, one continues with 3 reductions, 4 reductions, etc. until the password is found. If no chain contains the password, then the attack has failed.
# If this test is positive (step 3, ''linux23'' appears at the end of the chain and in the table), the password is retrieved at the beginning of the chain that produces ''linux23''. Here we find ''passwd'' at the beginning of the corresponding chain stored in the table. # If this test is positive (step 3, ''linux23'' appears at the end of the chain and in the table), the password is retrieved at the beginning of the chain that produces ''linux23''. Here we find ''passwd'' at the beginning of the corresponding chain stored in the table.
# At this point (step 4), one generates a chain and compares at each iteration the hash with the target hash. The test is valid and we find the hash ''re3xes'' in the chain. The current password (''culture'') is the one that produced the whole chain: the attack is successful. # At this point (step 4), one generates a chain and compares at each iteration the hash with the target hash. We find the hash ''re3xes'' in the chain, and the password that produced it (''culture'') one step earlier in the chain: the attack is successful.


] ]


Rainbow tables use a refined algorithm with a different reduction function for each "link" in a chain, so that when there is a hash collision in two or more chains, the chains will not merge as long as the collision doesn't occur at the same position in each chain. This increases the probability of a correct crack for a given table size, at the cost of squaring the number of steps required per lookup, as the lookup routine now also needs to iterate through the index of the first reduction function used in the chain.<ref name="ophpaper">{{Cite book|chapter-url=https://lasec.epfl.ch/pub/lasec/doc/Oech03.pdf|title=Advances in Cryptology - CRYPTO 2003|last1=Oechslin|first1=P.|year=2003|isbn=978-3-540-40674-7|series=]|volume=2729|pages=617–630|chapter=Making a Faster Cryptanalytic Time-Memory Trade-Off|doi=10.1007/978-3-540-45146-4_36}}</ref> Rainbow tables use a refined algorithm with a different reduction function for each "link" in a chain, so that when there is a hash collision in two or more chains, the chains will not merge as long as the collision doesn't occur at the same position in each chain. This increases the probability of a correct crack for a given table size, at the cost of squaring the number of steps required per lookup, as the lookup routine now also needs to iterate through the index of the first reduction function used in the chain.<ref name="ophpaper">{{Cite book|chapter-url=https://infoscience.epfl.ch/record/99512/files/Oech03.pdf|title=Advances in Cryptology - CRYPTO 2003|last1=Oechslin|first1=P.|year=2003|isbn=978-3-540-40674-7|series=]|volume=2729|pages=617–630|chapter=Making a Faster Cryptanalytic Time-Memory Trade-Off|doi=10.1007/978-3-540-45146-4_36|doi-access=free}}</ref>


Rainbow tables are specific to the hash function they were created for e.g., ] tables can crack only MD5 hashes. The theory of this technique was invented by Philippe Oechslin<ref></ref> as a fast form of ],<ref name="ophpaper"/> which he implemented in the ] ] ]. The more powerful ] program was later developed that can generate and use rainbow tables for a variety of character sets and hashing algorithms, including ], ], and ]. Rainbow tables are specific to the hash function they were created for e.g., ] tables can crack only MD5 hashes. The theory of this technique was invented by Philippe Oechslin<ref>{{Cite web |title=LASEC - Security and Cryptography Laboratory: Dr Philippe Oechslin - Research |author= |website=Faculté I&C - School of Computer and Communication Sciences |date=March 2004 |url= https://lasec.epfl.ch/people/oechslin/}}</ref> as a fast form of ],<ref name="ophpaper"/> which he implemented in the ] ] ]. The more powerful ] program was later developed that can generate and use rainbow tables for a variety of character sets and hashing algorithms, including ], ], and ].


In the simple case where the reduction function and the hash function have no collision, given a complete rainbow table (one that makes you sure to find the corresponding password given any hash) the size of the password set |''P''|, the time ''T'' that had been needed to compute the table, the length of the table ''L'' and the average time ''t'' needed to find a password matching a given hash are directly related:{{citation needed|date=July 2013}} In the simple case where the reduction function and the hash function have no collision, given a complete rainbow table (one that makes sure to find the corresponding password given any hash) the size of the password set |''P''|, the time ''T'' that had been needed to compute the table, the length of the table ''L'' and the average time ''t'' needed to find a password matching a given hash are directly related:{{citation needed|date=July 2013}}


:<math>T = |P| </math> :<math>T = |P| </math>
Line 89: Line 92:


The salt value is not secret and may be generated at random and stored with the password hash. A large salt value prevents precomputation attacks, including rainbow tables, by ensuring that each user's password is hashed uniquely. This means that two users with the same password will have different password hashes (assuming different salts are used). In order to succeed, an attacker needs to precompute tables for each possible salt value. The salt must be large enough, otherwise an attacker can make a table for each salt value. For older ] which used a 12-bit salt this would require 4096 tables, a significant increase in cost for the attacker, but not impractical with terabyte hard drives. The ] and ] methods—used in ], ] Unixes, and ]—have salts of 128 bits.<ref name="alexander">{{cite journal The salt value is not secret and may be generated at random and stored with the password hash. A large salt value prevents precomputation attacks, including rainbow tables, by ensuring that each user's password is hashed uniquely. This means that two users with the same password will have different password hashes (assuming different salts are used). In order to succeed, an attacker needs to precompute tables for each possible salt value. The salt must be large enough, otherwise an attacker can make a table for each salt value. For older ] which used a 12-bit salt this would require 4096 tables, a significant increase in cost for the attacker, but not impractical with terabyte hard drives. The ] and ] methods—used in ], ] Unixes, and ]—have salts of 128 bits.<ref name="alexander">{{cite journal
| url = http://www.usenix.org/publications/login/2004-06/pdfs/alexander.pdf | url = https://www.usenix.org/system/files/login/articles/1103-alexander.pdf | title = Password Protection for Modern Operating Systems | journal = Login | publisher = ] Association
| title = Password Protection for Modern Operating Systems | journal = Login | publisher = ] Association
| first = Steven | last = Alexander | volume = 29 |date=June 2004 | issue = 3 | first = Steven | last = Alexander | volume = 29 |date=June 2004 | issue = 3
}}</ref> These larger salt values make precomputation attacks against these systems infeasible for almost any length of a password. Even if the attacker could generate a million tables per second, they would still need billions of years to generate tables for all possible salts. }}</ref> These larger salt values make precomputation attacks against these systems infeasible for almost any length of a password. Even if the attacker could generate a million tables per second, they would still need billions of years to generate tables for all possible salts.
Line 109: Line 111:
}}</ref> It also greatly increases the time needed to build a precomputed table, but in the absence of salt, this needs only be done once. }}</ref> It also greatly increases the time needed to build a precomputed table, but in the absence of salt, this needs only be done once.


An alternative approach, called '''key strengthening''', extends the key with a random salt, but then (unlike in key stretching) securely deletes the salt. This forces both the attacker and legitimate users to perform a brute-force search for the salt value.<ref>{{Cite journal | doi = 10.1016/0167-4048(96)00003-X| title = A simple scheme to make passwords based on one-way functions much harder to crack| journal = Computers & Security| volume = 15| issue = 2| pages = 171–176| year = 1996| last1 = Manber | first1 = U. | author-link1 = Udi Manber| url = http://webglimpse.net/pubs/TR94-34.pdf| citeseerx = 10.1.1.102.2597}}</ref> Although the paper that introduced key stretching<ref name="low-entropy">{{Cite book | doi = 10.1007/BFb0030415| chapter-url = https://www.schneier.com/paper-low-entropy.pdf| chapter = Secure applications of low-entropy keys| title = Information Security| volume = 1396| pages = 121| series = ]| year = 1998| last1 = Kelsey | first1 = J. | author-link1= John Kelsey (cryptanalyst)| last2 = Schneier | first2 = B. | author-link2 = Bruce Schneier| last3 = Hall | first3 = C. | last4 = Wagner | first4 = D. | author-link4 = David A. Wagner| isbn = 978-3-540-64382-1}}</ref> referred to this earlier technique and intentionally chose a different name, the term "key strengthening" is now often (arguably incorrectly) used to refer to key stretching. An alternative approach, called '''key strengthening''', deploys two salts, one public and one secret, but then (unlike in key stretching) securely deletes the secret salt. This forces both the attacker and legitimate users to perform a brute-force search for the secret salt value. The secret salt size is chosen so that the brute force search is imperceptible to the legitimate user. However, it makes the rainbow dictionary needed by the attacker much larger.<ref>{{Cite journal| doi = 10.1016/0167-4048(96)00003-X| title = A simple scheme to make passwords based on one-way functions much harder to crack| journal = Computers & Security| volume = 15| issue = 2| pages = 171–176| year = 1996| last1 = Manber| first1 = U.| author-link1 = Udi Manber| url = http://webglimpse.net/pubs/TR94-34.pdf| citeseerx = 10.1.1.102.2597| access-date = 2015-08-28| archive-date = 2016-05-06| archive-url = https://web.archive.org/web/20160506230931/http://webglimpse.net/pubs/TR94-34.pdf| url-status = dead}}</ref> Although the paper that introduced key stretching<ref name="low-entropy">{{Cite book | doi = 10.1007/BFb0030415| chapter-url = https://www.schneier.com/wp-content/uploads/2016/02/paper-low-entropy.pdf| chapter = Secure applications of low-entropy keys| title = Information Security| volume = 1396| pages = 121| series = ]| year = 1998| last1 = Kelsey | first1 = J. | author-link1= John Kelsey (cryptanalyst)| last2 = Schneier | first2 = B. | author-link2 = Bruce Schneier| last3 = Hall | first3 = C. | last4 = Wagner | first4 = D. | author-link4 = David A. Wagner| isbn = 978-3-540-64382-1}}</ref> referred to this earlier technique and intentionally chose a different name, the term "key strengthening" is now often (arguably incorrectly) used to refer to key stretching.


Rainbow tables and other precomputation attacks do not work against passwords that contain symbols outside the range presupposed, or that are longer than those precomputed by the attacker. However, tables can be generated that take into account common ways in which users attempt to choose more secure passwords, such as adding a number or special character. Because of the sizable investment in computing processing, rainbow tables beyond fourteen places in length are not yet common. So, choosing a password that is longer than fourteen characters may force an attacker to resort to brute-force methods.{{Citation needed|date=January 2011}} Rainbow tables and other precomputation attacks do not work against passwords that contain symbols outside the range presupposed, or that are longer than those precomputed by the attacker. However, tables can be generated that take into account common ways in which users attempt to choose more secure passwords, such as adding a number or special character. Because of the sizable investment in computing processing, rainbow tables beyond fourteen places in length are not yet common. So, choosing a password that is longer than fourteen characters may force an attacker to resort to brute-force methods.{{Citation needed|date=January 2011}}


Specific intensive efforts focused on ], an older hash algorithm used by Microsoft, are publicly available. LM hash is particularly vulnerable because passwords longer than 7 characters are broken into two sections, each of which is hashed separately. Choosing a password that is fifteen characters or longer guarantees that an LM hash will not be generated.<ref>, ]</ref> Specific intensive efforts focused on ], an older hash algorithm used by Microsoft, are publicly available. LM hash is particularly vulnerable because passwords longer than 7 characters are broken into two sections, each of which is hashed separately. Choosing a password that is fifteen characters or longer guarantees that an LM hash will not be generated.<ref>{{Cite web|url=http://support.microsoft.com/kb/299656|title=How to prevent Windows from storing a LAN manager hash of your password in Active Directory and local SAM databases|date=24 September 2021|publisher=]}}</ref>


==Common uses== ==Common uses==


Nearly all distributions and variations of ], ], and ] use hashes with salts, though many applications use just a hash (typically ]) with no salt. The Microsoft Windows NT/2000 family uses the ] and ] hashing method (based on ]) and is also unsalted, which makes it one of the most popularly generated tables. Rainbow tables have seen reduced usage as of 2020 as salting is more common and GPU-based ] have become more practical. However, rainbow tables are available for eight and nine character ] passwords.<ref>{{Cite web|url=https://www.rainbowcrackalack.com|title=A Case for Modern Rainbow Table Usage|date=26 February 2021|website=rainbowcrackalack.com|publisher=Positron Security.}}</ref>


Nearly all distributions and variations of ], ], and ] use hashes with salts, though many applications use just a hash (typically ]) with no salt. The Microsoft Windows NT/2000 family uses the ] and ] hashing method (based on ]) and is also unsalted, which makes it one of the most popularly generated tables.


==See also== ==See also==
* ] * ]
* ] * ]
* ] * DistrRTgen
* ] * ]


Line 133: Line 133:
* {{Cite book * {{Cite book
| url = https://lasec.epfl.ch/pub/lasec/doc/Oech03.pdf | url = https://lasec.epfl.ch/pub/lasec/doc/Oech03.pdf
| first = Philippe
| title = Making a Faster Cryptanalytical Time-Memory Trade-Off
| last = Oechslin
| first = Philippe | last = Oechslin | chapter = Making a Faster Cryptanalytic Time-Memory Trade-Off
| journal = Advances in Cryptology: Proceedings of CRYPTO 2003, 23rd Annual International Cryptology Conference | title = Advances in Cryptology - CRYPTO 2003
| chapter = Making a Faster Cryptanalytic Time-Memory Trade-Off
| volume = 2729 | volume = 2729
| pages = 617–630 | pages = 617–630
| location = ], USA | date = 2003-08-17 | isbn = 978-3-540-40674-7 | publisher = Springer | series = Lecture Notes in Computer Science | location = ], USA
| date = 2003-08-17
| isbn = 978-3-540-40674-7
| publisher = Springer
| series = Lecture Notes in Computer Science
| doi = 10.1007/978-3-540-45146-4_36 | doi = 10.1007/978-3-540-45146-4_36
| s2cid = 16086595
| access-date = 2019-03-13
| archive-date = 2020-09-26
| archive-url = https://web.archive.org/web/20200926015126/https://lasec.epfl.ch/pub/lasec/doc/Oech03.pdf
| url-status = dead
}} }}


==External links== ==External links==
{{Prone to spam|date=April 2020}} {{Prone to spam|date=April 2020}}

{{Z148}}
* The original rainbow table research * The original rainbow table research
*{{DMOZ|Computers/Hacking/Cryptography/|Cryptography}}
{{cryptography navbox | hash}} {{cryptography navbox | hash}}


Line 152: Line 161:
] ]
] ]
] ]

Latest revision as of 12:15, 28 November 2024

Password cracking dataset

A rainbow table is a precomputed table for caching the outputs of a cryptographic hash function, usually for cracking password hashes. Passwords are typically stored not in plain text form, but as hash values. If such a database of hashed passwords falls into the hands of attackers, they can use a precomputed rainbow table to recover the plaintext passwords. A common defense against this attack is to compute the hashes using a key derivation function that adds a "salt" to each password before hashing it, with different passwords receiving different salts, which are stored in plain text along with the hash.

Rainbow tables are a practical example of a space–time tradeoff: they use less computer processing time and more storage than a brute-force attack which calculates a hash on every attempt, but more processing time and less storage than a simple table that stores the hash of every possible password.

Rainbow tables were invented by Philippe Oechslin as an application of an earlier, simpler algorithm by Martin Hellman.

Background

For user authentication, passwords are stored either as plaintext or hashes. Since passwords stored as plaintext are easily stolen if database access is compromised, databases typically store hashes instead. Thus, no one – including the authentication system – can learn a password merely by looking at the value stored in the database.

When a user enters a password for authentication, a hash is computed for it and then compared to the stored hash for that user. Authentication fails if the two hashes do not match; moreover, authentication would equally fail if a hashed value were entered as a password, since the authentication system would hash it a second time.

To learn a password from a hash is to find a string which, when input into the hash function, creates that same hash. This is the same as inverting the hash function.

Though brute-force attacks (e.g. dictionary attacks) may be used to try to invert a hash function, they can become infeasible when the set of possible passwords is large enough. An alternative to brute-force is to use precomputed hash chain tables. Rainbow tables are a special kind of such table that overcome certain technical difficulties.

Etymology

Rainbow Table illustration presented at Crypto 2003

The term rainbow tables was first used in Oechslin's initial paper. The term refers to the way different reduction functions are used to increase the success rate of the attack. The original method by Hellman uses many small tables with a different reduction function each. Rainbow tables are much bigger and use a different reduction function in each column. When colors are used to represent the reduction functions, a rainbow appears in the rainbow table. Figure 2 of Oechslin's paper contains a black-and-white graphic that illustrates how these sections are related. For his presentation at the Crypto 2003 conference, Oechslin added color to the graphic in order to make the rainbow association more clear. The enhanced graphic that was presented at the conference is shown in the illustration.

Precomputed hash chains

For hash chains other than what is mentioned here, see hash chain.

Given a password hash function H and a finite set of passwords P, the goal is to precompute a data structure that, given any output h of the hash function, can either locate an element p in P such that H(p) = h, or determine that there is no such p in P. The simplest way to do this is compute H(p) for all p in P, but then storing the table requires Θ(|P|n) bits of space, where |P| is the size of the set P and n is the size of an output of H, which is prohibitive for large |P|. Hash chains are a technique for decreasing this space requirement. The idea is to define a reduction function R that maps hash values back into values in P. Note, however, that the reduction function is not actually an inverse of the hash function, but rather a different function with a swapped domain and codomain of the hash function. By alternating the hash function with the reduction function, chains of alternating passwords and hash values are formed. For example, if P were the set of lowercase alphabetic 6-character passwords, and hash values were 32 bits long, a chain might look like this:

a a a a a a H 281 D A F 40 R s g f n y d H 920 E C F 10 R k i e b g t {\displaystyle {\color {Red}{\mathtt {aaaaaa}}}\,{\xrightarrow{}}\,{\mathtt {281DAF40}}\,{\xrightarrow{}}\,{\mathtt {sgfnyd}}\,{\xrightarrow{}}\,{\mathtt {920ECF10}}\,{\xrightarrow{}}\,{\color {Violet}{\mathtt {kiebgt}}}}

The only requirement for the reduction function is to be able to return a "plain text" value in a specific size.

To generate the table, we choose a random set of initial passwords from P, compute chains of some fixed length k for each one, and store only the first and last password in each chain. The first password is called the starting point and the last one is called the endpoint. In the example chain above, "aaaaaa" would be the starting point and "kiebgt" would be the endpoint, and none of the other passwords (or the hash values) would be stored.

Now, given a hash value h to invert (find the corresponding password for), compute a chain starting with h by applying R, then H, then R, and so on. If at any point a value matches one of the endpoints in the table, the corresponding starting point allows to recreate the complete chain. There's a high chance that this chain will contain the value h, and if so, the immediately preceding value in the chain is the password p that we seek.

For example, given the hash 920ECF10, its chain can be computed by first applying R:

920 E C F 10 R k i e b g t {\displaystyle {\mathtt {920ECF10}}\,{\xrightarrow{}}\,{\color {Violet}{\mathtt {kiebgt}}}}

Since "kiebgt" is one of the endpoints in our table, the corresponding starting password "aaaaaa" allows to follow its chain until 920ECF10 is reached:

a a a a a a H 281 D A F 40 R s g f n y d H 920 E C F 10 {\displaystyle {\color {Red}{\mathtt {aaaaaa}}}\,{\xrightarrow{}}\,{\mathtt {281DAF40}}\,{\xrightarrow{}}\,{\mathtt {sgfnyd}}\,{\xrightarrow{}}\,{\mathtt {920ECF10}}}

Thus, the password is "sgfnyd" (or a different password that has the same hash value).

Note however that this chain does not always contain the hash value h; it may so happen that the chain starting at h merges with a chain having a different starting point. For example, the chain of hash value FB107E70, also leads to kiebgt:

F B 107 E 70 R b v t d l l H 0 E E 80890 R k i e b g t {\displaystyle {\mathtt {FB107E70}}\,{\xrightarrow{}}\,{\mathtt {bvtdll}}\,{\xrightarrow{}}\,{\mathtt {0EE80890}}\,{\xrightarrow{}}\,{\color {Violet}{\mathtt {kiebgt}}}}

The chain generated by the corresponding starting password "aaaaaa" is then followed until FB107E70 is reached. The search will end without reaching FB107E70 because this value is not contained in the chain. This is called a false alarm. In this case, the match is ignored and the chain of h is extended looking for another match. If the chain of h gets extended to length k with no good matches, then the password was never produced in any of the chains.

The table content does not depend on the hash value to be inverted. It is created once and then repeatedly used for the lookups unmodified. Increasing the length of the chain decreases the size of the table. However, it also increases the time required to perform lookups, and this is the time-memory trade-off of the rainbow table. In a simple case of one-item chains, the lookup is very fast, but the table is very big. Once chains get longer, the lookup slows, but the table size goes down.

Simple hash chains have several flaws. Most serious if at any point two chains collide (produce the same value), they will merge and consequently the table will not cover as many passwords despite having paid the same computational cost to generate. Because previous chains are not stored in their entirety, this is impossible to detect efficiently. For example, if the third value in chain 3 matches the second value in chain 7, the two chains will cover almost the same sequence of values, but their final values will not be the same. The hash function H is unlikely to produce collisions as it is usually considered an important security feature not to do so, but the reduction function R, because of its need to correctly cover the likely plaintexts, cannot be collision resistant.

Other difficulties result from the importance of choosing the correct function for R. Picking R to be the identity is little better than a brute force approach. Only when the attacker has a good idea of likely plaintexts will they be able to choose a function R that makes sure time and space are only used for likely plaintexts, not the entire space of possible passwords. In effect R shepherds the results of prior hash calculations back to likely plaintexts but this benefit comes with the drawback that R likely won't produce every possible plaintext in the class the attacker wishes to check denying certainty to the attacker that no passwords came from their chosen class. Also it can be difficult to design the function R to match the expected distribution of plaintexts.

Rainbow tables

Rainbow tables effectively solve the problem of collisions with ordinary hash chains by replacing the single reduction function R with a sequence of related reduction functions R1 through Rk. In this way, for two chains to collide and merge they must hit the same value on the same iteration: consequently, the final values in these chain will be identical. A final postprocessing pass can sort the chains in the table and remove any "duplicate" chains that have the same final values as other chains. New chains are then generated to fill out the table. These chains are not collision-free (they may overlap briefly) but they will not merge, drastically reducing the overall number of collisions.

Using sequences of reduction functions changes how lookup is done: because the hash value of interest may be found at any location in the chain, it's necessary to generate k different chains. The first chain assumes the hash value is in the last hash position and just applies Rk; the next chain assumes the hash value is in the second-to-last hash position and applies Rk−1, then H, then Rk; and so on until the last chain, which applies all the reduction functions, alternating with H. This creates a new way of producing a false alarm: an incorrect "guess" of the position of the hash value may needlessly evaluate a chain.

Although rainbow tables have to follow more chains, they make up for this by having fewer tables: simple hash chain tables cannot grow beyond a certain size without rapidly becoming inefficient due to merging chains; to deal with this, they maintain multiple tables, and each lookup must search through each table. Rainbow tables can achieve similar performance with tables that are k times larger, allowing them to perform a factor of k fewer lookups.

Example

  1. Starting from the hash ("re3xes") in the image below, one computes the last reduction used in the table and checks whether the password appears in the last column of the table (step 1).
  2. If the test fails (rambo doesn't appear in the table), one computes a chain with the two last reductions (these two reductions are represented at step 2)
    Note: If this new test fails again, one continues with 3 reductions, 4 reductions, etc. until the password is found. If no chain contains the password, then the attack has failed.
  3. If this test is positive (step 3, linux23 appears at the end of the chain and in the table), the password is retrieved at the beginning of the chain that produces linux23. Here we find passwd at the beginning of the corresponding chain stored in the table.
  4. At this point (step 4), one generates a chain and compares at each iteration the hash with the target hash. We find the hash re3xes in the chain, and the password that produced it (culture) one step earlier in the chain: the attack is successful.

Rainbow tables use a refined algorithm with a different reduction function for each "link" in a chain, so that when there is a hash collision in two or more chains, the chains will not merge as long as the collision doesn't occur at the same position in each chain. This increases the probability of a correct crack for a given table size, at the cost of squaring the number of steps required per lookup, as the lookup routine now also needs to iterate through the index of the first reduction function used in the chain.

Rainbow tables are specific to the hash function they were created for e.g., MD5 tables can crack only MD5 hashes. The theory of this technique was invented by Philippe Oechslin as a fast form of time/memory tradeoff, which he implemented in the Windows password cracker Ophcrack. The more powerful RainbowCrack program was later developed that can generate and use rainbow tables for a variety of character sets and hashing algorithms, including LM hash, MD5, and SHA-1.

In the simple case where the reduction function and the hash function have no collision, given a complete rainbow table (one that makes sure to find the corresponding password given any hash) the size of the password set |P|, the time T that had been needed to compute the table, the length of the table L and the average time t needed to find a password matching a given hash are directly related:

T = | P | {\displaystyle T=|P|}
t = | P | 2 L {\displaystyle t={\frac {|P|}{2L}}}

Thus the 8-character lowercase alphanumeric passwords case (|P| ≃ 3×10) would be easily tractable with a personal computer while the 16-character lowercase alphanumeric passwords case (|P| ≃ 10) would be completely intractable.

Defense against rainbow tables

A rainbow table is ineffective against one-way hashes that include large salts. For example, consider a password hash that is generated using the following function (where "+" is the concatenation operator):

saltedhash(password) = hash(password + salt)

Or

saltedhash(password) = hash(hash(password) + salt)

The salt value is not secret and may be generated at random and stored with the password hash. A large salt value prevents precomputation attacks, including rainbow tables, by ensuring that each user's password is hashed uniquely. This means that two users with the same password will have different password hashes (assuming different salts are used). In order to succeed, an attacker needs to precompute tables for each possible salt value. The salt must be large enough, otherwise an attacker can make a table for each salt value. For older Unix passwords which used a 12-bit salt this would require 4096 tables, a significant increase in cost for the attacker, but not impractical with terabyte hard drives. The SHA2-crypt and bcrypt methods—used in Linux, BSD Unixes, and Solaris—have salts of 128 bits. These larger salt values make precomputation attacks against these systems infeasible for almost any length of a password. Even if the attacker could generate a million tables per second, they would still need billions of years to generate tables for all possible salts.

Another technique that helps prevent precomputation attacks is key stretching. When stretching is used, the salt, password, and some intermediate hash values are run through the underlying hash function multiple times to increase the computation time required to hash each password. For instance, MD5-Crypt uses a 1000 iteration loop that repeatedly feeds the salt, password, and current intermediate hash value back into the underlying MD5 hash function. The user's password hash is the concatenation of the salt value (which is not secret) and the final hash. The extra time is not noticeable to users because they have to wait only a fraction of a second each time they log in. On the other hand, stretching reduces the effectiveness of brute-force attacks in proportion to the number of iterations because it reduces the number of attempts an attacker can perform in a given time frame. This principle is applied in MD5-Crypt and in bcrypt. It also greatly increases the time needed to build a precomputed table, but in the absence of salt, this needs only be done once.

An alternative approach, called key strengthening, deploys two salts, one public and one secret, but then (unlike in key stretching) securely deletes the secret salt. This forces both the attacker and legitimate users to perform a brute-force search for the secret salt value. The secret salt size is chosen so that the brute force search is imperceptible to the legitimate user. However, it makes the rainbow dictionary needed by the attacker much larger. Although the paper that introduced key stretching referred to this earlier technique and intentionally chose a different name, the term "key strengthening" is now often (arguably incorrectly) used to refer to key stretching.

Rainbow tables and other precomputation attacks do not work against passwords that contain symbols outside the range presupposed, or that are longer than those precomputed by the attacker. However, tables can be generated that take into account common ways in which users attempt to choose more secure passwords, such as adding a number or special character. Because of the sizable investment in computing processing, rainbow tables beyond fourteen places in length are not yet common. So, choosing a password that is longer than fourteen characters may force an attacker to resort to brute-force methods.

Specific intensive efforts focused on LM hash, an older hash algorithm used by Microsoft, are publicly available. LM hash is particularly vulnerable because passwords longer than 7 characters are broken into two sections, each of which is hashed separately. Choosing a password that is fifteen characters or longer guarantees that an LM hash will not be generated.

Common uses

Nearly all distributions and variations of Unix, Linux, and BSD use hashes with salts, though many applications use just a hash (typically MD5) with no salt. The Microsoft Windows NT/2000 family uses the LAN Manager and NT LAN Manager hashing method (based on MD4) and is also unsalted, which makes it one of the most popularly generated tables. Rainbow tables have seen reduced usage as of 2020 as salting is more common and GPU-based brute force attacks have become more practical. However, rainbow tables are available for eight and nine character NTLM passwords.

See also

Notes

  1. ^ Oechslin, P. (2003). "Making a Faster Cryptanalytic Time-Memory Trade-Off" (PDF). Advances in Cryptology - CRYPTO 2003. LNCS. Vol. 2729. pp. 617–630. doi:10.1007/978-3-540-45146-4_36. ISBN 978-3-540-40674-7.
  2. ^ Hellman, M. (1980). "A cryptanalytic time-memory trade-off" (PDF). IEEE Transactions on Information Theory. 26 (4): 401–406. CiteSeerX 10.1.1.120.2463. doi:10.1109/TIT.1980.1056220. ISSN 0018-9448. S2CID 552536.
  3. "LASEC - Security and Cryptography Laboratory: Dr Philippe Oechslin - Research". Faculté I&C - School of Computer and Communication Sciences. March 2004.
  4. ^ Alexander, Steven (June 2004). "Password Protection for Modern Operating Systems" (PDF). Login. 29 (3). USENIX Association.
  5. Ferguson, Neils; Bruce Schneier (2003). Practical Cryptography. Indianapolis: John Wiley & Sons. ISBN 978-0-471-22357-3.
  6. Provos, Niels; Mazières, David (June 6, 1999). "A Future-Adaptable Password Scheme" (PDF). Proceedings of the FREENIX Track: 1999 USENIX Annual Technical Conference. Monterey, CA, USA: USENIX Association.
  7. Manber, U. (1996). "A simple scheme to make passwords based on one-way functions much harder to crack" (PDF). Computers & Security. 15 (2): 171–176. CiteSeerX 10.1.1.102.2597. doi:10.1016/0167-4048(96)00003-X. Archived from the original (PDF) on 2016-05-06. Retrieved 2015-08-28.
  8. Kelsey, J.; Schneier, B.; Hall, C.; Wagner, D. (1998). "Secure applications of low-entropy keys" (PDF). Information Security. LNCS. Vol. 1396. p. 121. doi:10.1007/BFb0030415. ISBN 978-3-540-64382-1.
  9. "How to prevent Windows from storing a LAN manager hash of your password in Active Directory and local SAM databases". Microsoft. 24 September 2021.
  10. "A Case for Modern Rainbow Table Usage". rainbowcrackalack.com. Positron Security. 26 February 2021.

References

External links

Cryptographic hash functions and message authentication codes
Common functions
SHA-3 finalists
Other functions
Password hashing/
key stretching functions
General purpose
key derivation functions
MAC functions
Authenticated
encryption
modes
Attacks
Design
Standardization
Utilization
Cryptography
General
Mathematics
Categories: