Шифрование, кэширование и пароли — в помощь студенту

Эти три термина часто путают — они означают три абсолютно разных вещи. Для того, чтобы понять разницу, давайте сначала проясним некоторые моменты.

alt

Узнай стоимость своей работы

Бесплатная оценка заказа!

Оценим за полчаса!

С точки зрения безопасности, когда вы отправляете данные/сообщение в интернете:

  • Вы хотите, чтобы другой человек знал, что это письмо отправили вы, а не кто-либо другой.
  • Вы хотите, чтобы сообщение получили в том же формате, в каком вы отправили — без изменений.
  • Вы хотите, чтобы ваше сообщение не могли прочитать злоумышленники.

Шифрование, кэширование и пароли - в помощь студенту

Эти три пункта можно назвать по-другому:

  • Проверка личности
  • Целостность сообщения
  • Конфиденциальность

Чтобы это было возможным, используются хеширование и шифрование. Начнем с хеширования.

Хеширование

Давайте представим жизнь без хеширования. Например, сегодня день рождения друга, и вы хотите отправить ему поздравление. Ваш веселый товарищ-ботан решает над вами посмеяться, перехватывает сообщение и превращает «С Днем рождения» в «Покойся с миром». Это вполне вероятно, и вы, возможно, даже об этом не узнаете.

Чтобы такого не случалось, на помощь приходит хеширование — оно защищает целостность данных.

alt

Узнай стоимость своей работы

Бесплатная оценка заказа!
Читайте также:  Операционная система windows - в помощь студенту

Оценим за полчаса!

Хеш — это число, которое генерируется из текста с помощью хеш-алгоритма. Это число меньше оригинального текста.

Шифрование, кэширование и пароли - в помощь студентуАлгоритм хеширования

Алгоритм работает так, что для каждого текста генерируется уникальный хеш. И восстановить текст из хеша, перехватив сообщение, практически невозможно.

Одно из незаменимых свойств хеширования — его уникальность. Одно и то же значение хеша не может использоваться для разного текста. Малейшее изменение в тексте полностью изменит значение хеша. Это называется эффектом лавины.

В примере ниже мы использовали алгоритм SHA-1.

Текст: Все любят пончики.
Значение SHA-1 текста: daebbfdea9a516477d489f32c982a1ba1855bcd

Давайте не будем оспаривать фразу про пончики и сосредоточимся пока на хешировании. Теперь если мы немного поменяем текст, хеш полностью изменится.

  • Текст: Все любят пончик.
    Значение SHA-1 текста: 8f2bd584a1854d37f9e98f9ec4da6d757940f388
  • Как вы видите, поменялась одна буква, а хеш изменился до неузнаваемости.
  • Хеширование нужно:
  • Чтобы информация в базах данных не дублировалась;
  • Для цифровых подписей и SSL-сертификатов;
  • Чтобы найти конкретную информацию в больших базах данных;
  • В компьютерной графике.

Почти невозможно представить интернет без шифрования. Шифрование — это то, что делает интернет безопасным. При шифровании конфиденциальная информация превращается в нечитаемый формат, чтобы хакер не смог ее перехватить.

Шифрование, кэширование и пароли - в помощь студентуШифрование и дешифровка

Данные шифруются с помощью криптографических ключей. Информация шифруется до отправления и расшифровывается получателем. Таким образом, при передаче данные находятся в безопасности.

В зависимости от природы ключей шифрование может делиться на 2 категории: симметричное и асимметричное.

Симметричное шифрование: Данные шифруются и расшифровываются при помощи одного криптографического ключа. Это значит, что ключ, используемый для шифрования, используется и для расшифровки.

Асимметричное шифрование: Это довольно новый метод. В нем используются два разных ключа — один для шифрования, второй для расшифровки. Один ключ называется публичным, второй секретным.

Публичные ключи везде — у вас он тоже есть, даже если вы об этом не знаете. Один из них сохраняется в вашем браузере каждый раз, когда вы заходите на сайт с SSL-сертификатом.

Когда вы отправляете данные на зашифрованный сайт, этот сайт закодирован публичным ключом. Приватный ключ есть только у получателя, и он должен хранить его в недоступном месте. Секретный ключ расшифровывает зашифрованные данные. Когда используются два разных ключа, шифрование проходит безопаснее и чуть медленнее.

Оба эти метода используются в SSL/TLS-сертификатах. Асимметричное шифрование сначала применяется к процессу рукопожатия SSL — валидации сервера. Как только между клиентом и сервером устанавливается соединение, данные шифруются с помощью симметричного шифрования.

Кодировка

В отличие от шифрования и хеширования кодировка используется не в целях безопасности. При кодировке данные превращаются в другие форматы, чтобы множество систем могли их использовать.

В кодировке не используются ключи. Алгоритм, который берется для кодировки данных, также используется, чтобы раскодировать их. ASCII и UNICODE — примеры таких алгоритмов кодировки.

Резюмируем

  1. Хеширование: ряд цифр, который генерируется, чтобы подтвердить целостность данных с помощью алгоритмов хэширования.
  2. Шифрование: Метод, который используется, чтобы зашифровать данные, превратив их в формат, не поддающийся расшифровке.
  3. Кодировка: Превращение данных из одного формата в другой.
  4. Источник: статья в блоге Cheap SSL Security

Источник: https://SSL.com.ua/blog/hashing-coding-encryption/

Хеширование и шифрование паролей

Я использую членство ASP.NET для сайта, который будет обслуживать в первую очередь сложных пользователей. Я понимаю разницу между хешированными и зашифрованными паролями, и я пытаюсь решить между ними.

После того, как мой последний клиент с горечью жаловался на хешированные пароли, являющиеся полной PITA, я начал пользоваться зашифрованными паролями. Но кто-то предложил это просто недостаточно безопасно.

Итак, мой вопрос: что, собственно, риски шифрования паролей? Любой человек, у которого есть возможность похищать пароли, расшифровывая их из базы данных, несомненно, будет иметь возможность reset их, если они были хэшированы, нет? У меня возникли проблемы с тем, что кто-то может вызвать проблемы с зашифрованными паролями, но не мог с хэшированными. Удобство для пользователей также важно.

Риск с расшифровкой паролей заключается в том, что люди используют один пароль для разных учетных записей и учетных записей, а не только для приложения, с которым вы имеете дело.

  • С зашифрованным паролем
    украденный/расшифрованный пароль может быть
    опробовали другие учетные записи пользователей (например, украденный банковский пароль мог привести к доступу к их электронной почте).
  • С хешированным паролем нет
    восстановление. Кража хэшей паролей
    никогда не должно легко приносить пользу
    Пароли

Лечить пароли как свойство владельца учетной записи. Это не ваше, чтобы просматривать, расшифровывать или делать другие вещи. Если пользователь забыл свой пароль, предложите reset, а не извлечение.

Дело в том, что зашифрованные пароли можно расшифровать… так что возможно, что с доступом к ключам и т.д. все пароли могут быть известны.

Пароли Hashed (с солью) — это одна функция, поэтому нет эффективного способа определить, что такое пароль, что означает, что пользователю, предоставляющему пароль, меньше беспокоиться.

Конечно, кто-то может изменить хэш в том месте, где он хранится (например, база данных), чтобы пользователь больше не мог войти в систему, но пароль, который они предоставили изначально, до сих пор не будет известен.

Edit
Поскольку вы отметили вопрос ASP.Net, я бы рекомендовал использовать библиотеку BCrypt.Net для генерации ваших хэшей

  • Риск состоит в том, что зашифрованные пароли могут быть дешифрованы для получения пароля обычного текста.
  • Хэши обычно не могут быть отменены.
  • Реверсирование хеша MD5
  • Довольно распространенное явление — люди, использующие одинаковые имя пользователя и пароль на всех своих интернет-сайтах.
  • Все, что требуется, — это один пароль сайта, который будет расшифрован, и все сайты пользователей находятся под угрозой.
  • Пока с хешем, взломщик никогда не получает пароль обычного текста.

Как говорили другие пользователи, зашифрованные пароли могут быть дешифрованы и не являются хорошей идеей.

Если вы используете стандартную хеш-технику, пользователь, у которого есть доступ к вашей базе данных, может, например, ввести стандартный md5 для «пароля».

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

Храните его где-то в безопасности и используйте sha1 ($ salt. $Input). Теперь у вас есть соленый хэш.

Шифрование, кэширование и пароли - в помощь студенту

Источник: https://techarks.ru/qa/heshirovanie-i-shifrovanie-par-OJ/

Надлежащее хэширование паролей

Надлежащее хэширование паролей

Взломщики хэшей в наши дни стали крайне эффективны, настолько, что большинство паролей можно взломать за незначительное время. Даже длинные пароли, подвергнутые однократному хэшированию перестали быть безопасными.

Авторы: bwall (@bwallHatesTwits), drone (@dronesec)

   

Очевидно, что мы должны были написать данную статью, поскольку бесчисленные сервисы, которым мы доверяем наши пароли, обращаются с ними безответственно. Взломщики хэшей в наши дни стали крайне эффективны, настолько, что большинство паролей можно взломать за незначительное время.

Даже длинные пароли, подвергнутые однократному хэшированию перестали быть безопасными.

Сначала мы рассмотрим текущее положение вещей, далее – то, почему ваш сервис не должен легко относится к данной проблеме, а затем различные способы, которыми вы можете улучшить ваше хранилище паролей.

 

1.1 Текущее положение

 

Как свидетельствуют недавние дампы различных баз данных паролей, большинство веб-сайтов не хранят пароли своих пользователей надлежащим образом.

Хранение паролей открытым текстом или с единственным алгоритмом хэширования без соли кажется вполне традиционным. Это безответственно.

Если вы действительно хотите сохранить себе миллисекунды вычислительного времени вместо нормальной защиты своих пользователей, тогда я лично и открыто буду высказываться против вашего сервиса.

 

1.2 Моральное обязательство

 

Если вы каким либо образом храните чьи-то пароли, вы несете за них ответственность.

Каждый раз, когда кто-нибудь взламывает базу данных и раскрывает пароли, хранящиеся в открытом виде, или слабые хэши, все пострадавшие пользователи должны не только поменять свои пароли к каждому сервису, для которого использовался раскрытый пароль, но и задуматься, хотят ли они продолжать использовать взломанный сервис. Если вы не защищаете пароли должным образом, в какой-то момент времени вы почувствуете последствия этого. Потратьте время на надлежащую генерацию и хранение хэшей паролей и энтропии.

 

2 Надлежащие методы хэширования

 

Просто хэшировать пароль недостаточно. Нужно делать это должным образом. Вот несколько методов и руководящих указаний.

 

2.1 Соль хороша для вас

 

Соль, касающаяся хэшей, метафорически схожа с пищевой солью. Вы также приправляете ей ваш хэш. Единственное отличие в том, что мы хотим нечто большего при использовании соли в хэше.

Соли паролей – тип энтропии, которая делает различными хэши, вычисленные по одинаковому алгоритму от одинакового текста. Это делается путем хэширования соли совместно с открытым текстом.

Одной соли недостаточно для обеспечения безопасности хэша, но с ней хэш лучше, чем без нее.

 

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

Вот почему важно, чтобы для каждого хэша использовалась уникальная соль (предпочтительно являющаяся случайным набором байтов): не только, чтобы гарантировать отсутствие коллизии пользовательских паролей, если они одинаковы, но и чтобы увеличить вычислительную сложность и размер атаки по словарю или перебором. Не повторяйте соль.

 

2.2 Функции получения ключей

 

Довольно любопытно, что лучшие функции для хэширования паролей первоначально предназначались для генерации ключей шифрования из значений, не подходящих на роль ключа.

Данные функции обрабатывают входные данные криптографическим образом и возвращают набор байтов, которые могут быть использованы, как ключ шифрования.

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

 

2.2.1 PBKDF2

 

PBKDF2 (Password-Based Key Derivation Function 2 или Функция Получения Ключа На Основе Пароля 2) – это функция получения ключа, разработанная RSA Laboratories, используемая для получения стойких ключей на основе хэша.

Она работает путем применения псевдослучайной хэш-функции (вроде SHA-256, SHA-512, и т. д.) к строке, в нашем случае – к паролю, вместе с солью и повторением этого процесса большое число раз.

Данный процесс может быть обобщен следующей диаграммой:

Шифрование, кэширование и пароли - в помощь студенту  

Мы уже обсудили вопрос соли, однако, стоит отметить, что минимальная длина рекомендуемой соли для PBKDF – 128 бит. Спецификация1 PBKDF утверждает, что SHA-12 является утвержденной PRF (псевдослучайной функцией) для алгоритма. Однако, в 2005 году стало ясно, что SHA-1 – относительно слабая функция3 и не должна использоваться как HMAC.

В ваших интересах использовать достаточно сильный HMAC, чтобы выдержать полный перебор, специальные атаки и потенциальные будущие проблемы дизайна (вроде взлома алгоритма или вычислительной достижимости). Важно отметить разницу между хэшем и HMAC – хэш не связан с аутентификацией сообщения. Он связан только с целостностью данных.

Читайте также:  Особенности земельного права - в помощь студенту

HMAC обычно используется для подписи сообщений при хэшировании их с солью, уникальной для ее владельца. HMAC также можно использовать для генерации очень сильных хэшей. Проблема в том, что при известной соли HMAC столь же легко взломать полным перебором.

Здесь на выручку приходит PBKDF2, реализующая итеративный HMAC, который увеличивает безопасность и время взлома каждого отдельного хэша. Давайте взглянем на псевдокод этого процесса:

 1 bytes PBKDF2(HashAlgo, Plaintext, Salt, Iterations) { bytes IterativeHash = hash_hmac(HashAlgo, Salt, Plaintext); bytes TempHash = IterativeHash; for(int iter = 0; iter < Iterations; iter++)

{ TempHash = hash_hmac(HashAlgo, TempHash, Plaintext); IterativeHash ^= TempHash } return IterativeHash; }

 

Это упрощенная версия полного псевдокода. Она также должным образом модифицирована, чтобы мы смогли оптимально использовать ее как функцию хэширования, а не как функцию получения ключа. Вот ее PHP-реализация:

 function PBKDF2($plain, $salt, $iterations, $algo = 'sha256' ) { $derivedkey = $b = hash_hmac($algo, $salt . pack('N', $block), $plain, true); for ( $i = 0; $i < $iterations; $i++ )

{ $derivedkey ^= ($b = hash_hmac($algo, $b, $plain, true)); } return $derivedkey; }

 

Хоть вышеприведенные примеры и обобщены, они дают базовый взгляд на то, как может быть реализована функция PBKDF2.

Здесь всего лишь хэшируется соль и открытый текст для получения первого хэша, затем в цикле тот же алгоритм используется для вычисления хэша от открытого текста и результата предыдущей итерации, после чего возвращается результат применения операции XOR ко всем вычисленным хэшам.

Выполнив данную операцию 1000 или больше раз, вы сгенерируете сильный, стойкий ко взлому хэш, который вы можете безопасно использовать для хранения паролей. За подробностями можете обратиться к NIST-SP800-132.

 

2.2.2 ARC4PBKDF2

 

Я (bwall) некоторое время обыгрывал в уме идею динамической энтропии. PBKDF2 кажется хорошей площадкой для ее внедрения. Данная идея заключается в том, чтобы сделать энтропию алгоритма шифрования изменяющейся в ходе шифрования.

Она происходит из ограничений некоторых систем быстрого взлома хэшей, которые имеют тенденцию жестко оптимизировать определенные процессы вроде применения энтропии.

Чтобы бороться с этим, мы можем добавить относительно быстрый процесс создания дополнительной энтропии, который потребует дополнительных вычислений в ходе взлома хэша и возможного удаления некоторых оптимизаций.

В ARC4PBKDF2 поток шифра ARC4 инициализируется ключом, затем данный шифр используется для шифрования открытого текста перед его использованием в HMAC в каждой итерации, продолжая тот же поток и также шифруя результат HMAC. Этот поток ARC4 должен быть единым для всего процесса, чтобы добавить сложности и в без того трудный для взлома метод хэширования. Далее представлен пример реализации на C#.

 public byte[] Hash(byte[] input) { ARC4 rc4 = new ARC4(ARC4Key); byte[] derived = new HMACSHA256(Salt).ComputeHash(rc4.CryptBytes(input)); byte[] temp = derived; for (int x = 0; x < Iterations; x++) { temp = rc4.CryptBytes(new HMACSHA256(temp).ComputeHash(rc4.CryptBytes(input)));

for (int y = 0; y < derived.Length; y++) { derived[y] ^= temp[y]; } } return derived; }

 

Важно отметить, что в данной реализации ARC4 метод CryptBytes продолжает использовать один поток ARC4, так что каждое шифрование делается в разных частях потока. Динамическая энтропия – новая, экспериментальная идея, которую еще предстоит обсудить тем, кто разрабатывает методы оптимизации, на борьбу с которыми она направлена.

 

2.2.3 bcrypt

 

Bcrypt – адаптивная хэш-функция, появившаяся в 1999 году. Она немного походит на PBKDF2, но действует более сложным образом. Первую работу, связанную с данной функцией, опубликованную Наелсом Провосом и Дэвидом Мазьересом, можно найти здесь. Она очень подробно объясняет тонкости алгоритма и его реализацию. Для наших целей будет достаточно краткого обзора с примером.

 

По сути, bcrypt – это блочный шифр Blowfish4, используемый в режиме ECB, с более сложным алгоримом подготовки ключей (особенно, что касается S-блоков).

Это позволяет алгоритму быть стойким к возможным будущим атакам и существенно более адаптивным.

Реализация алгоритма использует 128-битную соль и усовершенствованный алгоритм, известный, как eksblowfish или expensive key schedule blowfish. Заголовок функции bcrypt выглядит так:

  bcrypt(cost, salt, pwd)  

Здесь cost – контроллер подготовки ключей (задает ресурсоемкость фазы подготовки ключей), salt – 128-битное значение, а pwd – текстовый (до 56 байтов) ключ, используемый для шифрования по алгоритму Blowfish.

 

Существует пара действительно удивительных, полезных вещей, касающихся bcrypt и заслуживающих обсуждения. Одна из них – то, что алгоритму НЕОБХОДИМА соль. Хотя соль сама по себе не сохранит ваш украденный SQL-дамп, она увеличит его стойкость.

Вторая – то, что алгоритм является (я использовал этот термин уже несколько раз) адаптивным. Время подготовки ключей может быть всего порядка одной миллисекунды или таким большим, как вы захотите.

Замечательный факт состоит в том, что для сервера почти безразлично, что проверка пароля занимает 3 секунды вместо 0.3, но для атакующего такое увеличение сложности – абсолютный хаос.

Это также позволяет напрямую бороться с экспоненциальным наращиванием вычислительных мощностей (известным, как закон Мура), поскольку со временем вы можете постепенно изменять значение переменной cost, чтобы увеличить сложность паролей.

 

Bcrypt – одна из наиболее популярных функций получения ключей (следущая по популярности за PBKDF2), и почти для каждого языка программирования доступна ее надежная реализация.

Если вас заинтересовал продвинутый алгоритм подготовки ключей, рекомендуем вам прочесть официальный документ, упомянутый выше.

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

 public string bcrypt(int cost, byte[] salt, byte[] password) { byte[] state = EksBlowFishSetup(cost, salt, password); string ciphertext = «OrpheanBeholderScryDoubt»; for (int i = 0; i < 64; ++i) { ciphertext = EncryptECB(state, ciphertext); }

return cost.ToString() + BitConverter.ToString(salt) + ciphertext; }

 

Вышеприведенный код довольно прост. Сначала значение переменной state устанавливается алгоритмом EksBlowFish – данная стадия является наиболее емкой по времени.

Далее идет цикл получения шифртекста, изначально имеющего значение 192-битной магической строки (почти всегда равной «OrpheanBeholderScryDoubt»), путем многократного шифрования шифртекста из предыдущей итерации в режиме ECB вместе со значением переменной state.

Итоговый результат – статическая 192-битная конкатенация стоимости, соли и результирующего шифртекста.

 

3 Заключение

 

Рассмотренные методы значительно увеличивают время, требуемое для взлома хэшей. Не существует предлога не использовать упомянутые эти методы для хранения паролей.

Мы понимаем, что оперирование хэшами может быть сложным, особенно, если вы не понимаете их как следует.

Мы в Ballast Security работаем над решением этой проблемы, чтобы даже те, кто не имеет понятия, как обезопасить пароли, смогли бы сделать это ценой минимальных усилий.

 

Ссылки и материалы для дальнейшего чтения

 

[0] Bruce Schneier’s description of the BlowFish cipher https://www.schneier.com/paper-blowfish-fse.html     [1] Niels Provos’ and David Mazieres original paper on Bcrypt http://static.usenix.org/events/usenix99/provos.html     [2] NIST SP800-132: Recommendation for Password-Based Key Derivation http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf   

 [3] FIPS 180-1 on Secure Hashing http://www.itl.nist.gov/fipspubs/fip180-1.htm

  1 http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf 2 http://www.itl.nist.gov/fipspubs/fip180-1.htm 3 https://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html 4 https://www.schneier.com/paper-blowfish-fse.html   

Источник: https://www.securitylab.ru/analytics/427930.php

Как хранить пароли в БД (PHP). Шифрование, хеширование паролей

Главная причина — минимизация ущерба в случае утечки базы данных.

Если злоумышленник получит только логины и email-адреса пользователей — это плохо, но не критично.

Но если в его руках окажутся логины и пароли, он может попытаться использовать эти данные для входа в почтовые сервисы (Gmail, Яндекс.Почта, Mail.ru и т.д.), социальные сети, мессенджеры, клиент-банки и т.д.

В тот же личный кабинет Пятёрочки, чтобы перевыпустить карту и потратить чужие бонусы.

Шифрование, кэширование и пароли - в помощь студенту

В общем, пользователи сайта, которые везде используют одни и те же логины и пароли, могут получить кучу проблем.

Некоторые разработчики считают, что их приложение надёжно защищено и никаких утечек быть не может. Есть несколько причин, почему это мнение ошибочно:

  • Разработчик — не робот, он не может не совершать ошибок.
  • Взлом может произойти со стороны хостинг-провайдера, работу которого не всегда возможно контролировать.
  • Некорректная настройка сервера может привести к возможному доступу других пользователей хостинга к вашему сайту (актуально для виртуальных хостингов).
  • Бывший коллега по работе может слить базу данных конкурентам. Может в качестве мести, а может просто ради денег.

Короче, пароли в открытом виде хранить нельзя.

Шифрование и хеширование

  • Шифрование — это обратимое преобразование текста в случайный набор символов.
  • Хеширование — это необратимое преобразование текста в случайный набор символов.
  • Разница между этими двумя действиями в том, можем ли мы из случайного набора символов получить исходную строку по какому-то известному алгоритму.
  • Приведу пример шифрования. У нас есть сообщение:

Я Вася

Зашифруем сообщение по следующему алгоритму: сдвинем каждую букву на 1 в алфавитном порядке, т.е.

а превращается в б, г превращается в д, я превращается в а. Так будет выглядеть зашифрованный текст:

А Гбта

Зашифровали. Теперь для расшифровки нужно выполнить обратную операцию, сдвинуть все буквы на 1 символ назад. К слову, этот алгоритм шифрования называется шифр Цезаря (Википедия).

В отличие от шифрования, хеширование не имеет (вернее, не должно иметь) способа «расхешировать» строку обратно:

$hash = md5('Какая-то строка');

Шифрование паролей

Не надо шифровать пароли.

Алгоритм дешифровки можно украсть или подобрать. При использовании хеширования неважно, знает ли его алгоритм злоумышленник, это не особо поможет ему в получении исходного пароля из хеша.

Хеширование паролей и авторизация

Для хеширования паролей в PHP существует функция password_hash():

$password = '123456';
$hash = password_hash($password, PASSWORD_BCRYPT);

var_dump($hash);
// string(60) «$2y$10$Vb.pry5vRGNrm6Y79UfBsun/RbXq2.XEGCOMpozrDwg.MNpfxvWHK»

Вторым параметром передаётся алгоритм хеширования. По-умолчанию это указанный нами bcrypt, но я рекомендую указывать его вручную, поскольку базовый алгоритм в будущем может поменяться. Будет грустно, если при очередном обновлении версии PHP на сайте отвалится авторизация.

Для проверки корректности введённого пользователем пароля используется функция password_verify():

Источник: https://www.programulin.ru/kak-hranit-paroli-v-bd-php

Алгоритмы хеширования — простое объяснение сложного — Крипто на vc.ru

Одним из ключевых слов, которые новички слышат, когда узнают о блокчейне, являются понятия хэша и алгоритма хэширования, которые кажутся распространёнными для безопасности.

Запуск децентрализованной сети и консенсуса, такой как биткойн или сеть эфириум с десятками тысяч узлов, соединенных через p2p, требует, как “надежности”, так и эффективности проверки.

То есть, эти системы нуждаются в способах кодирования информации в компактном формате, позволяющем обеспечить безопасную и быструю проверку ее участниками

Основным примитивом, обрабатываемым как Биткойном, так и Эфириумом, является понятие блока, который представляет собой структуру данных, включающую транзакции, временную метку и другие важные метаданные.

Критическая часть их безопасности включает в себя возможность сжимать большие куски информации о глобальном состоянии сети в короткий стандарт сообщений, который может быть эффективно проверен, если это необходимо, известный как хэш.

Даже изменение одного символа во входных данных приведет к совершенно другому хэшу.

Криптографические хэши используются везде, от хранения паролей до систем проверки файлов.

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

То есть, использование одного и того же ввода всегда приводит к одному и тому же результату. Детерминизм важен не только для хэшей, но и для одного бита, который изменяется во входных данных, создавая совершенно другой хэш. Проблема с алгоритмами хэширования — неизбежность коллизий.

То есть, тот факт, что хэши являются строкой фиксированной длины, означает, что для каждого ввода, который мы можем себе представить, есть другие возможные входы, которые приведут к тому же хэшу. Коллизия — это плохо.

Это означает, что, если злоумышленник может создавать коллизии, он может передавать вредоносные файлы или данные, как имеющие правильный и неправильный хэш и скрываться под правильным хешем.

Цель хорошей хэш-функции состоит в том, чтобы сделать чрезвычайно сложным для злоумышленников найти способы генерации входных данных, которые хешируются с одинаковым значением. Вычисление хэша не должно быть слишком простым, так как это облегчает злоумышленникам искусственное вычисление коллизий. Алгоритмы хэширования должны быть устойчивы к «атакам нахождения прообраза». То есть, получая хеш, было бы чрезвычайно сложно вычислить обратные детерминированные шаги, предпринятые для воспроизведения значения, которое создало хэш (т.е нахождение прообраза).

Учитывая S = hash (x), найти X должно быть почти невозможно.

Напомним, что «хорошие» алгоритмы хэширования имеют следующие свойства:

  • Изменение одного бита во входных данных должно создать эффект изменения всего хеша;
  • Вычисления хеша не должно быть слишком простым, высокая сложность нахождения прообраза;
  • Должен иметь очень низкую вероятность коллизии;

Взлом хешей

Одним из первых стандартов алгоритма хэширования был MD5 hash, который широко использовался для проверки целостности файлов (контрольных сумм) и хранения хэшированных паролей в базах данных веб-приложений.

Его функциональность довольно проста, так как она выводит фиксированную 128-битную строку для каждого входа и использует тривиальные однонаправленные операции в нескольких раундах для вычисления детерминированного результата.

Его короткая выходная длина и простота операций сделали MD5 очень легким для взлома и восприимчивым к атаке «дня рождения».

Что такое «Атака дня рождения?»

Вы когда-нибудь слышали о том, что если вы поместите 23 человека в комнату, есть 50% шанс, что у двух из них будет один и тот же день рождения? Доведение числа до 70 человек в комнате дает вам 99,9% шанс.

Если голуби рассажены в коробки, причем число голубей больше числа коробок, то хотя бы в одной из клеток находится более одного голубя.

То есть фиксированные ограничения на выход означают, что существует фиксированная степень перестановок, на которых можно найти коллизию.

Источник: https://vc.ru/crypto/47132-algoritmy-heshirovaniya-prostoe-obyasnenie-slozhnogo

Зачем нужны хэш функции, и как сохранить пароли в секрете

Время от времени хотим мы этого или нет, но происходят взломы серверов баз данных. Учитывая это, важно быть уверенным в том, что конфиденциальные данные, такие как пароли пользователей, не будут раскрыты. Сегодня, мы осветим тему хэширования и мер по защите паролей в вашем web приложении.

1. Пару слов перед тем, как начнём

Криптология это достаточно сложная тема в которой я далеко не эксперт. По сей день различные университеты и организации по безопасности занимаются исследованиями в этой области.

В этой статье я постараюсь излагаться как можно проще, на тему прочного метода хранения паролей в web-приложениях

2. Зачем нужно «Хэширование»?

Хеширование превращает данные в набор строковых и целочисленных элементов.

Это происходит благодаря одностороннему хэшированию. «Одностороннее» означает, что произвести обратное преобразование ну очень уж сложно или вовсе невозможно.

Самая распространённая хэш функция это md5():

$data = «Hello World»;
$hash = md5($data);
echo $hash; // b10a8db164e0754105b7a99be72e3fe5

Применяя md5(), вы всегда будете получать в качестве результата строку размером 32 символа. Но эти символы будут в шестнадцатеричном виде; технически хэш может представлять собой и 128-битовое целое.

Читайте также:  История возникновения денег - в помощь студенту

Вы можете помещать в функцию md5() строки и числа любой длины, но на выходе всегда будете получать результат в 32 символа. Уже только этот факт хорошее подтверждение тому, что это «односторонняя» функция.

3. Использование хэш функций для хранения паролей

Обычный процесс регистрации:

  • Пользователь заполняет форму регистрации, включая поле «Пароль».
  • Скрипт-обработчик помещает эти данные в базу данных.
  • Перед записью в базу, пароль обрабатывается хэш функцией.
  • Оригинальное значение пароля нигде не используется.

Процесс входа в систему:

  • Пользователь вводит свой логин и пароль.
  • Скрипт-обработчик хэширует пароль, который ввёл пользователь.
  • Скрипт находит запись в базе данных, и считывает значения пароля, который хранится в ней.
  • Пароль из базы и пароль введённый пользователем сравниваются, и если они совпадают (в хэшированном виде), то пользователя впускают в систему.

Процесс хэширования пароля будет изложен далее в этой статье.

Заметьте, что оригинальное значение пароли нигде не сохранялось. Если база данных попадёт к злоумышленникам, то они не смогуть увидеть пароли, так? Да не совсем… Давайте посмотрим на потенциальные «дыры».

4. Проблема #1: Коллизии

“Коллизии” возникают тогда когда при хэшировании двух данных разного типа, получается один и тот же результат. Вообще-то это зависит от того какую функцию вы используете.

Как это можно использовать?

К примеру, я видел несколько устаревшие скрипты, где для хэширования пароля использовалась функция crc32(). Эта функция возвращает в качестве результат 32-битное целое. Это означает, что на выходе может быть только 2^32 (или 4,294,967,296) возможных вариантов.

Давайте захэшируем пароль:

echo crc32('supersecretpassword');
// на выходе: 323322056

Теперь, давайте поиграем в злодея, который украл базу данных вместе с хэшированным паролем. У нас нет возможности преобразовать 323322056 в ‘supersecretpassword’, однако, благодаря простому скрипту мы можем подобрать другой пароль, который в хэшированном виде будет точно такой же как и тот, который находится в базе:

set_time_limit(0);
$i = 0;
while (true) {

if (crc32(base64_encode($i)) == 323322056) {
echo base64_encode($i);
exit;
}

$i++;
}

Этому скрипту конечно нужно время, но в конце концов он вернёт строку. Теперь мы можем использовать строку, которую получили — вместо ‘supersecretpassword’ — что позволит нам зайти в систему от имени пользователя у которого был этот пароль.

Например вот этот скрипт через несколько мгновений возвратил мне строчку ‘MTIxMjY5MTAwNg==‘. Давайте протестируем:

echo crc32('supersecretpassword');
// на выходе: 323322056

echo crc32('MTIxMjY5MTAwNg==');
// на выходе: 323322056

Как это можно предотвратить?

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

К примеру можно использовать md5(), которая генерирует 128-битные хэши. Таким образом вариантов подбора становится намного больше 340,282,366,920,938,463,463,374,607,431,768,211,456. Пробег по всем итерациям с целью нахождения коллизии невозможен. Однако некоторым людям всё же удаётся найти «дыры» дополнительно об этом тут).

Sha1

Sha1() это лучшая альтернатива т.к. она возвращает 160-битный хэш.

5. Проблема #2: Радужная таблица

  • Даже если мы разобрались с коллизиями, это не значит, что мы обезопасили себя со всех сторон.
  • Радужная таблица строится путём вычисления хэш-значения наиболее часто используемых слов и словосочетаний.
  • Такие таблицы могут содержать миллионы, а то и миллиарды строк.

К примеру, для создания такой таблицы можно пройтись по словарю и создать хэш для каждого слова. Так же можно создавать хэши для комбинации слов.

Но и это не всё; вы можете так же вставлять цифры перед/после/между слов, и тоже записывать значение таких хэшей в таблицу.

Вот такие огромные Радужные Таблицы могут быть составлены и использованы.

Как это можно использовать:

Давайте представим, что у нас в руках база с десятками тысяч паролей. Особого труда не составит, чтобы сравнить их с значениями из Радужной таблицы. Конечно же не все пароли совпадут, но в конечном итоге парочка другая найдётся!

Как можно себя защитить:

Просто добавим «соли»:

$password = «easypassword»;

// такой пароль может найтись в Радужной таблице
// т.к. пароль содержит два распространённых слова
echo sha1($password); // 6c94d3b42518febd4ad747801d50a8972022f956

// для соли используем любое количество случайных символов
$salt = «f#@V)Hu^%Hgfds»;

// такой хэш никогда не будет найден в Радужных таблицах
echo sha1($salt . $password); // cd56a16759623378628c0d9336af69b74d9d71a5

Всё, что нужно сделать, это сконкатенировать “соль” и пароль перед хэшированием. Навряд ли в Радужных таблицах найдётся такое значение. Но мы всё ещё в опасности!

6. Проблема #3: И снова Радужные таблицы

Помните, что Радужные таблицы могут быть сформированы уже после того, как база будет украдена.

Как это можно использовать?

Если вы создали соль, то при краже базы она попадёт в руки злоумышленникам. Всё, что им останется сделать это сгенерировать новую Радужную таблицу с «солями», которые они получили из базы.

К примеру в Радужной таблице есть хэш строки “easypassword”. В новой Радужной таблице вместо прошлого значения у них будет содержаться строка “f#@V)Hu^%Hgfdseasypassword”. Когда они запустят скрипт, то снова могут получить некоторые совпадения.

Как защититься?

Мы можем использовать “уникальную соль” которая будет разной для каждого пользователя.

Дополнением к соли для того, чтоб она стала уникальной может стать id пользователя:

$hash = sha1($user_id . $password);

Это само собой подразумевает, что id пользователя никогда не будет меняться.

Так же мы можем сгенерировать случайную строку для каждого отдельного пользователя, чем получим «уникальную соль». Такую соль нужно хранить там же, где находится запись о пользователе.

// сгенерируем строку длиной 22 символа
function unique_salt() {
return substr(sha1(mt_rand()),0,22);
}

$unique_salt = unique_salt();

$hash = sha1($unique_salt . $password);

// сохраним $unique_salt в записи пользователя
// …

Этот метод защищает нас от Радужных таблиц, т.к. у каждого пароля есть своя уникальная соль. Атакующему придётся создать 10 миллионов отдельных Радужных таблиц, что на практике невыполнимо.

7. Проблема #4: Скорость выполнения

Большинство функций хэширования разрабатывались, учитывая то, что они часто используются для расчёта контрольных сумм каких-то значений или файлов с проверкой целостности данных.

Как это использовать?

Как я говорил ранее, компьютер с мощной графической картой может высчитывать миллиарды хэшей за секунду. Злоумышленники могут применить «грубую силу», проверяя каждый единственно возможный пароль (проводя полный перебор всех возможных вариантов).

Если вы думаете, что пароль из 8 символов может устоять перед «грубой атакой», то представьте:

  • Если пароль содержит прописные, заглавные буквы и цифры, это всего лишь 62 (26+26+10) возможных символа.
  • Строка из 8 символов содержит 62^8 вариантов комбинаций. Это чуть больше 218 триллионов.
  • Если обрабатывать 1 миллиард хэшей за секунду, пароль будет подобран за 60 часов.

Для пароля длиной 6 символов та же самая операция будет длиться более 1 минуты.

Не стесняйтесь требовать от пользователей пароли длиной 9 или 10 символов, хотя это и будет их нервировать.

Как защищаться?

Используйте медленные хэш функции

Представьте себе, что вы используете хэш функцию, которая генерирует 1 миллион хэшей в секунду вместо 1 миллиарда. Атакующему предётся в 1000 раз дольше подбирать пароли. 60 часов превратятся в 7 лет!

Первый вариант самому создать такую функцию:

function myhash($password, $unique_salt) {

$salt = «f#@V)Hu^%Hgfds»;
$hash = sha1($unique_salt . $password);

// делать в 1000 раз дольше
for ($i = 0; $i < 1000; $i++) { $hash = sha1($hash); } return $hash; }

Или вы можете использовать алгоритм, который использует «cost параметр,» такой как BLOWFISH. В PHP, это может быть реализовано с помощью метода crypt().

function myhash($password, $unique_salt) {
// соль для blowfish должна быть на 22 символа больше
return crypt($password, '$2a$10$'.$unique_salt);
}

Второй параметр в методе crypt() содержит значения, разделённые знаками доллара ($).

Первое значение это '$2a', которое говорит, что мы будем использовать алгоритм BLOWFISH.

Второе значение '$10'. В этом случает это «cost параметр». Это параметр представляет собой количество итераций, которые будут производиться (10 => 2^10 = 1024 итераций.) Значение может быть от 04 до 31.

Давайте запустим пример:

function myhash($password, $unique_salt) {
return crypt($password, '$2a$10$'.$unique_salt);

}
function unique_salt() {
return substr(sha1(mt_rand()),0,22);
}

$password = «verysecret»;

echo myhash($password, unique_salt());
// результат: $2a$10$dfda807d832b094184faeu1elwhtR2Xhtuvs3R9J1nfRGBCudCCzC

В результате у нас получился хэш, который содержит алгоритм ($2a), cost параметр ($10), и соль длиной 22 символа. Всё остальное это хэш. Протестируем:

// допустим, что мы получили это из базы
$hash = '$2a$10$dfda807d832b094184faeu1elwhtR2Xhtuvs3R9J1nfRGBCudCCzC';

// предположим, что пользователь ввёл пароль «verysecret»
$password = «verysecret»;

if (check_password($hash, $password)) {
echo «Доступ разрешён!»;
} else {
echo «Доступ запрещён!»;
}

function check_password($hash, $password) {
// первые 29 символов это алгоритм, cost и соль
$full_salt = substr($hash, 0, 29);

// запустим хэш функцию для $password
$new_hash = crypt($password, $full_salt);

// вернём true или false
return ($hash == $new_hash);
}

Если мы это запустим, то получим сообщение «Доступ разрешён!»

8. Собираем всё в кучу

Учитывая всё, что мы узнали, напишем класс:

class PassHash {

// blowfish
private static $algo = '$2a';

// cost параметр
private static $cost = '$10';

// для наших нужд
public static function unique_salt() {
return substr(sha1(mt_rand()),0,22);
}

// генерация хэша
public static function hash($password) {
return crypt($password,
self::$algo .
self::$cost .
'$' . self::unique_salt());

}

// сравнение пароля и хэша
public static function check_password($hash, $password) {
$full_salt = substr($hash, 0, 29);

$new_hash = crypt($password, $full_salt);

return ($hash == $new_hash);
}
}

Применяем при регистрации:

// инклудим class
require («PassHash.php»);

// читаем $_POST
// …

// валидируем все поля
// …

// хэшируем пароль
$pass_hash = PassHash::hash($_POST['password']);

// сохраняем всё в БД, кроме $_POST['password']
// вместо которого у нас теперь $pass_hash
// …

Использование при входе пользователя в систему:

// инклудим class
require («PassHash.php»);

// читаем $_POST
// …

// достаём запись из базы по $_POST['username'] или чему-то другому
// …

// проверяем пароль, который был введён пользователем
if (PassHash::check_password($user['pass_hash'], $_POST['password'])) {
// доступ открыт
// …
} else {
// доступ закрыт
// …
}

9. Проверка на возможность использования Blowfish

Алгоритм Blowfish может и не быть реализован на всех системах, хоть и очень популярен. Проверка на возможность использования:

if (CRYPT_BLOWFISH == 1) {
echo «Да»;
} else {
echo «Нет»;
}

Однако, начиная с PHP 5.3, этот алгоритм встроен по умолчанию.

Заключение

Этого метода хэширования вполне достаточно для большинства web-приложений. Так же не забывайте: что вы в праве требовать минимальную длину пароля от своих пользователей. Вы так же можете перемешивать символы, цифры и специальные знаки.

Вопрос к вам: как вы хэшируете ваши пароли? Что думаете по поводу методов в данной статье?

Источник: https://ruseller.com/lessons.php?id=902

Безопасное хеширование паролей

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

Почему я должен хешировать пароли пользователей в моем приложении?

Хеширование паролей является одним из самых основных соображений безопасности, которые необходимо сделать, при разработке приложения, принимающего пароли от пользователей.

Без хеширования, пароли, хранящиеся в базе вашего приложения, могут быть украдены, например, если ваша база данных была скомпрометирована, а затем немедленно могут быть применены для компрометации не только вашего приложения, но и аккаунтов ваших пользователей на других сервисах, если они не используют уникальных паролей.

Применяя хеширующий алгоритм к пользовательским паролям перед сохранением их в своей базе данных, вы делаете невозможным разгадывание оригинального пароля для атакующего вашу базу данных, в то же время сохраняя возможность сравнения полученного хеша с оригинальным паролем.

Важно заметить, однако, что хеширование паролей защищает их только от компрометирования в вашем хранилище, но не обязательно от вмешательства вредоносного кода в вашем приложении.

Почему популярные хеширующие функции, такие как md5() и sha1() не подходят для паролей?

Такие хеширующие алгоритмы как MD5, SHA1 и SHA256 были спроектированы очень быстрыми и эффективными. При наличии современных технологий и оборудования, стало довольно просто выяснить результат этих алгоритмов методом «грубой силы» для определения оригинальных вводимых данных.

Из-за той скорости, с которой современные компьютеры могут «обратить» эти хеширующие алгоритмы, многие профессионалы компьютерной безопасности строго не рекомендуют использовать их для хеширования паролей.

Если популярные хеширующие функции не подходят, как же я тогда должен хешировать свои пароли?

При хешировании паролей существует два важных соображения: это стоимость вычисления и соль. Чем выше стоимость вычисления хеширующего алгоритма, тем больше времени требуется для взлома его вывода методом «грубой силы».

PHP 5.5 предоставляет встроенное API хеширования паролей, которое безопасно работает и с хешированием и с проверкой паролей. Также есть » библиотека PHP для совместимости, доступная с PHP 5.3.7.

Другой возможностью является функция crypt(), которая поддерживает несколько алгоритмов хеширования в PHP 5.3 и новее. При использовании этой функции вы можете быть уверенным, что выбранный вами алгоритм доступен, так как PHP содержит собственную реализацию каждого поддерживаемого алгоритма, даже в случае, если какие-то из них не поддерживаются вашей системой.

При хешировании паролей рекомендуется применять алгоритм Blowfish, который также используется по умолчанию в API хеширования паролей, так как он значительно большей вычислительной сложности, чем MD5 или SHA1, при этом по-прежнему гибок.

Учтите, что, если вы используете функцию crypt() для проверки пароля, то вам нужно предостеречь себя от атак по времени, применяя сравнение строк, которое занимает постоянное время.

Ни операторы PHP == и ===, ни функция strcmp() не являются таковыми. Функция же password_verify() как раз делает то, что нужно.

Настоятельно рекомендуется использовать встроенное API хеширования паролей, если есть такая возможность.

Что такое соль?

Криптографическая соль представляет собой данные, которые применяются в процессе хеширования для предотвращения возможности разгадать оригинальный ввод с помощью поиска результата хеширования в списке заранее вычисленных пар ввод-хеш, известном также как «радужная» таблица.

Более простыми словами, соль — это кусочек дополнительных данных, которые делают ваши хеши намного более устойчивыми к взлому. Существует много онлайн-сервисов, предоставляющих обширные списки заранее вычисленных хешей вместе с их оригинальным вводом. Использование соли делает поиск результирующего хеша в таком списке маловероятным или даже невозможным.

password_hash() создает случайную соль в случае, если она не была передана, и чаще всего это наилучший и безопасный выбор.

Как я должен хранить свою соль?

При использовании функции password_hash() или crypt(), возвращаемое значение уже содержит соль как часть созданного хеша. Это значение нужно хранить как есть в вашей базе данных, так как оно содержит также информацию о хеширующей функции, которая использовалась, и может быть непосредственно передано в функции password_verify() или crypt() при проверке пароля.

Следующая диаграмма показывает формат возвращаемого значения функциями crypt() или password_hash(). Как можно видеть, они содержат полную информацию об алгоритме и соли, требуемых для будущей проверки пароля.

alf dot henrik at ascdevel dot com

Источник: https://www.php.net/manual/ru/faq.passwords.php

Ссылка на основную публикацию