Оптимальный коэффициент работы bcrypt

Что было бы идеальным рабочим фактором bcrypt для хеширования паролей.

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

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

Как вы решаете компромисс между безопасностью перебора и эксплуатационными затратами?

4 ответа

Решение

Помните, что значение хранится в пароле: $2a$(2 chars work)$(22 chars salt)(31 chars hash), Это не фиксированное значение.

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

Хитрость заключается в том, чтобы держать это в течение примерно одинакового количества времени навсегда в будущем вместе с законом Мура. Это число log2, поэтому каждый раз, когда скорость компьютера увеличивается вдвое, добавьте 1 к номеру по умолчанию.

Решите, сколько времени вы хотите, чтобы перебор пароля пользователя. Например, для некоторых общих слов в словаре создание вашей учетной записи уже предупредило их, что их пароль был слабым. Скажем, если это одно из 1000 распространенных слов, и злоумышленнику требуется 0,1 с, чтобы протестировать каждое, которое покупает их по 100 с (ну, некоторые слова встречаются чаще...). Если пользователь выбрал "общее словарное слово" + 2 цифры, это более двух часов. Если ваша база паролей скомпрометирована, и злоумышленник может получить только несколько сотен паролей в день, вы купили большинство своих пользователей часами или днями, чтобы безопасно сменить их пароли. Это вопрос выигрыша времени.

http://www.postgresql.org/docs/8.3/static/pgcrypto.html есть несколько вариантов взлома паролей, которые вы можете рассмотреть. Конечно, в паролях, которые они перечисляют, есть случайные буквы. Словарные слова... Практически говоря, вы не можете спасти парня с паролем 12345.

Укороченная версия

Количество итераций, дающее не менее 250 мс на вычисление

Длинная версия

Когда BCrypt был впервые опубликован в 1999 году, они перечислили факторы стоимости своей реализации по умолчанию:

  • обычный пользователь: 6
  • суперпользователь: 8

Стоимость bcrypt, равная 6, означает 64 раунда (26 = 64).

Также они отмечают:

Конечно, какую бы стоимость ни выбирали люди, ее следует время от времени пересматривать.

  • На момент развертывания в 1976 году crypt мог хэшировать менее 4 паролей в секунду. (250 мс на пароль)
  • В 1977 году на VAX-11/780 крипта (MD5) могла оцениваться примерно 3,6 раза в секунду. (277 мс на пароль)

Это дает вам представление о задержках, которые учитывали первоначальные разработчики, когда писали это:

  • ~250 мс для обычных пользователей
  • ~1 секунда для суперпользователей.

Но, конечно, чем дольше выдержишь, тем лучше. Каждая реализация BCrypt, которую я видел, использовала10как стоимость по умолчанию. И моя реализация использовала это. Я считаю, что мне пора увеличить стоимость по умолчанию до 12.

Мы решили, что хотим нацелить не менее 250 мс на хэш.

Мой настольный ПК - это процессор Intel Core i7-2700K @ 3,50 ГГц. Изначально я тестировал реализацию BCrypt 23.01.2014:

1/23/2014  Intel Core i7-2700K CPU @ 3.50 GHz

| Cost | Iterations        |    Duration |
|------|-------------------|-------------|
|  8   |    256 iterations |     38.2 ms | <-- minimum allowed by BCrypt
|  9   |    512 iterations |     74.8 ms |
| 10   |  1,024 iterations |    152.4 ms | <-- current default (BCRYPT_COST=10)
| 11   |  2,048 iterations |    296.6 ms |
| 12   |  4,096 iterations |    594.3 ms |
| 13   |  8,192 iterations |  1,169.5 ms |
| 14   | 16,384 iterations |  2,338.8 ms |
| 15   | 32,768 iterations |  4,656.0 ms |
| 16   | 65,536 iterations |  9,302.2 ms |

Будущее

Вместо фиксированной константы она должна быть фиксированным минимумом.

Вместо того, чтобы иметь хеш-функцию вашего пароля:

String HashPassword(String password)
{
   return BCrypt.HashPassword(password, BCRYPT_DEFAULT_COST);
}

это должно быть примерно так:

String HashPassword(String password)
{  
   /*
     Rather than using a fixed default cost, run a micro-benchmark
     to figure out how fast the CPU is.
     Use that to make sure that it takes **at least** 250ms to calculate
     the hash
   */
   Int32 costFactor = this.CalculateIdealCost();
   //Never use a cost lower than the default hard-coded cost
   if (costFactor < BCRYPT_DEFAULT_COST) 
      costFactor = BCRYPT_DEFAULT_COST;

   return BCrypt.HashPassword(password, costFactor);
}

Int32 CalculateIdealCost()
{
    //Benchmark using a cost of 5 (the second-lowest allowed)
    Int32 cost = 5;

    var sw = new Stopwatch();
    sw.Start();
    this.HashPassword("microbenchmark", cost);
    sw.Stop();

    Double durationMS = sw.Elapsed.TotalMilliseconds;

    //Increasing cost by 1 would double the run time.
    //Keep increasing cost until the estimated duration is over 250 ms
    while (durationMS < 250)
    {
       cost += 1;
       durationMS *= 2;
    }

    return cost;
}

И в идеале это должно быть частью библиотеки BCrypt каждого, поэтому вместо того, чтобы полагаться на то, что пользователи библиотеки периодически увеличивают стоимость, она периодически увеличивается сама.

Я пытался определить оптимальное количество раундов обработки bcrypt и хотел опубликовать свои выводы. Как отмечали другие, идеальное количество раундов зависит от вашего оборудования, терпения вашего пользователя и оборудования потенциальных злоумышленников.

В 2023 году, работая на базовом динамометрическом стенде Heroku, а затем снова на своей локальной машине, я измерил, сколько времени занимает выполнение хэш-операции для ряда различных соляных раундов:

Биты энтропии для слабого пароля на основе знаменитого комикса о паролях XKCD

Факторы, которые следует учитывать:

  • Время взлома можно разделить на количество компьютеров, к которым у вас есть доступ. Хакеры с бот-сетями или большим количеством средств могут разделить время взлома на порядки.

  • Время взлома со временем уменьшается. Хешированные пароли, которые стали известны сейчас, могут быть легко взломаны через 10 лет.

  • 5600X далек от вершины современной обработки. 7900X сможет сделать это быстрее.

  • Это было сделано в однопоточном режиме, многопоточность сделает это быстрее.

Основываясь на этих данных, я бы посоветовал минимум 10 раундов, но настоятельно рекомендую 11. 100–200 мс — это очень короткий период времени для ожидания пользователя, и если одновременные входы в систему вызывают задержку, вам следует учитывать добавив больше мощности в ваш сервер. Максимум, что я бы посоветовал, это 13 раундов. Хотя это будет очень безопасно, 700 мс — это длительный срок для пользователей, чтобы ждать входа в систему. Между 10 и 13 годами вам, как разработчику, придется принять решение.

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

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

Примечание. Как рассчитать время взлома?

Чтобы обсудить это, нам сначала нужно обсудить энтропию паролей. Очень кратко: энтропия пароля рассчитывается на основе системы, которую вы используете для подбора пароля. Таким образом, если ваш пароль представляет собой 4-значный PIN-код, вы можете выбрать только 10 000 возможных PIN-кодов. Таким образом, ваш пароль имеет энтропию 10000. Обычно это называют 13 битами энтропии, поскольку 10000 ≈ 2¹³.

Чтобы определить, сколько времени понадобится злоумышленнику, чтобы взломать ваш пароль, все, что вам нужно, это определить, сколько в среднем ему потребуется угадать. Для этого четырехзначного PIN-кода они могли угадать его с первой попытки или потребуется 10 000 попыток. Но в среднем злоумышленнику потребуется 5000 попыток. Таким образом, время, необходимое для проверки одного пароля, умноженное на количество требуемых попыток, и есть время взлома.

Вопрос касался оптимального и практического определения фактора стоимости хэшей паролей bcrypt.

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

Фактор стоимости Bcrypt = 6 + (количество лет членства пользователя или некоторый его коэффициент) с дополнительным потолком общей стоимости, возможно, каким-то образом измененным частотой входа в систему этого пользователя.

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

Другие вопросы по тегам