Limit zxcvbn entropy estimation length

Limit the use of zxcvbn based password entropy estimation to 256 bytes. After this threshold, the average per-byte entropy from the zxcvbn calculation is added for each additional byte. In practice, this produces a slightly higher entropy calculation for purely randomized passwords than zxcvbn would normally calculate. However, the time to calculate is capped leading to a much better user experience and removing unnecessary calculations.

Fixes #7712
This commit is contained in:
Patrick Sean Klein 2022-04-03 17:31:15 +02:00 committed by Jonathan White
parent dca70f809d
commit 6f28b5e2ba
6 changed files with 156 additions and 107 deletions

View file

@ -21,10 +21,32 @@
#include "PasswordHealth.h"
#include "zxcvbn.h"
PasswordHealth::PasswordHealth(double entropy)
: m_score(entropy)
, m_entropy(entropy)
namespace
{
const static int ZXCVBN_ESTIMATE_THRESHOLD = 256;
} // namespace
PasswordHealth::PasswordHealth(double entropy)
{
init(entropy);
}
PasswordHealth::PasswordHealth(const QString& pwd)
{
auto entropy = 0.0;
entropy += ZxcvbnMatch(pwd.left(ZXCVBN_ESTIMATE_THRESHOLD).toUtf8(), nullptr, nullptr);
if (pwd.length() > ZXCVBN_ESTIMATE_THRESHOLD) {
// Add the average entropy per character for any characters above the estimate threshold
auto average = entropy / ZXCVBN_ESTIMATE_THRESHOLD;
entropy += average * (pwd.length() - ZXCVBN_ESTIMATE_THRESHOLD);
}
init(entropy);
}
void PasswordHealth::init(double entropy)
{
m_score = m_entropy = entropy;
switch (quality()) {
case Quality::Bad:
case Quality::Poor:
@ -43,11 +65,6 @@ PasswordHealth::PasswordHealth(double entropy)
}
}
PasswordHealth::PasswordHealth(const QString& pwd)
: PasswordHealth(ZxcvbnMatch(pwd.toUtf8(), nullptr, nullptr))
{
}
void PasswordHealth::setScore(int score)
{
m_score = score;