"Tomu se dá snadno zabránit takzvaným solením, při němž se otisky počítají z hesel doplněných o nějakou další hodnotu (sůl), takže i když dva uživatelé budou mít stejné heslo, odpovídající otisky budou odlišné."
Ano, ale jen v případě nekonstantní soli, jinak samozřejmě heslo1 == heslo2 => hash(heslo1.salt) == hash(heslo2.salt).
"Zbývá ještě zmínit bezkoliznost, která zajišťuje, že pro různé vstupy budou vypočítány různé otisky (i drobné změně vstupu by měly odpovídat velké změny výsledného otisku)."
A tady jste smíchal bezkoliznost s jednosměrností.
Nechci být drzý, ale od odborníka na počítačovou bezpečnost bych čekal přesnější vyjadřování.
Ale to je přeci známý fakt, že každý uživatel má jinou sůl, takže to ani není nutné zmiňovat ;) Nebo když už se tedy vůbec solí že by se to fakt implementovalo tak že sůl je konstantní a nejlépe v databázi aby si to útočník mohl předpočítat rainbow tables? No minimálně ho to o nějakou dobu pozdrží. A nezapomínejme že žijeme v době SSD a GPU, a taky pozor na SQL injection a některá exotičtější kódování UTF...
Třeba v případě přihlašování HTTP DIGEST je sůl konstantní, protože je jí identifikace serveru.
Výhoda rainbow tables je v tom, že už jsou předpočítané. Když je bude muset útočník počítat znova i pro konstantní sůl, reálně je může spočítat jen pro malou množinu hesel, tedy pro slabá a často se opakující hesla.