Я читал этот учебник, и я столкнулся с следующим обсуждением шифрования. В конце написано
В последней строке weve hashed соль с паролем, что дает зашифрованный пароль, который фактически невозможно сломать
Но, на мой взгляд, хакер, у которого есть как encrypted_password
, так и salt
, может сделать трюк "радуги" точно так же, как если бы мы использовали salt
.
Итак, где я ошибаюсь?
Спасибо!
$ rails console >> require 'digest' >> def secure_hash(string) >> Digest::SHA2.hexdigest(string) >> end => nil >> password = "secret" => "secret" >> encrypted_password = secure_hash(password) => "2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b" >> submitted_password = "secret" => "secret" >> encrypted_password == secure_hash(submitted_password) => true
Здесь мы определили функцию, называемую secure_hash, который использует криптографическую хэш-функция, называемая SHA2, часть SHA-семейства хеш-функций, которые мы включить в Ruby через дайджест библиотеки .7 Не важно знать точно, как работают эти хэш-функции; для наших целей важно что они односторонние: нет с вычислительной точки зрения что
2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b представляет собой SHA2-хэш строки "Секрет".
Если вы думаете об этом, однако, мы все еще есть проблема: если злоумышленник когда-либо овладевали хэшированными паролями, у него все равно будет шанс на открывая оригиналы. Для Например, он мог догадаться, что мы использовали SHA2, и поэтому напишите программу для сравнить хэш с хэшем значения потенциальных паролей:
>> hash = "2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b" >> secure_hash("secede") == hash => false >> secure_hash("second") == hash => false >> secure_hash("secret") == hash => true
Итак, у нашего злоумышленника есть плохие новости матча для любых пользователей с паролем "секретный". Этот метод известен как радуга атака.
Чтобы сорвать потенциальную радужную атаку, мы может использовать соль, которая отличается уникальная строка для каждого пользователя8. общий способ (почти) обеспечить уникальность заключается в хешировании текущего времени (в UTC быть независимым от часового пояса) вместе с паролем, чтобы два пользователи будут иметь такую же соль, только если они создаются точно так же времени и имеют одинаковый пароль. Давайте как это работает, используя Функция secure_hash, определенная в консоль выше:
>> Time.now.utc => Fri Jan 29 18:11:27 UTC 2010 >> password = "secret" => "secret" >> salt = secure_hash("#{Time.now.utc}--#{password}") => "d1a3eb8c9aab32ec19cfda810d2ab351873b5dca4e16e7f57b3c1932113314c8" >> encrypted_password = secure_hash("#{salt}--#{password}") => "69a98a49b7fd103058639be84fb88c19c998c8ad3639cfc5deb458018561c847"
В последней строке weve hashed соль с паролем, что дает зашифрованный пароль, который фактически невозможно сломать. (Для ясности, аргументы для хэш-функций часто разделяются -.)