-1

I'm using the password_strength package from PyPi to assess password strength, using a policy of PasswordPolicy.from_names(strength=x).

The package documentation suggests that x=0.66 is a good choice. I've set up a random password generator, producing passwords containing upper- and lower-case letters, numerals and special symbols. For this password to pass strength=0.66, it needs to be 15 characters long. Is that what we're really advocating these days for website passwords?

To get that down to eight random characters, I have to set strength=0.25. I don't really have much grasp of what this "strength" number means, but that seems a long way below the recommendation.

Can someone explain what this number is in words a simpleton like me can understand? What's a reasonable number for a website password these days?

Edit The answer is really making me wonder if password strength is an appropriate measure to use. According to this, qwerty123 has exactly the same strength as m#U0(Bp94.

Tom
  • 7,269
  • 1
  • 42
  • 69

2 Answers2

0

Strength is simply a logical scoring of passwords whose values ranges from [0, 1] which means weak and strong password repectively.Password strength is a measure of the effectiveness of a password against guessing or brute-force attacks.

So if you try

from password_strength import PasswordStats

stats = PasswordStats('qwerty123')
print(stats.strength())  #-> Its strength is 0.316

stats = PasswordStats('G00dPassw0rd?!')
print(stats.strength())  #-> Its strength is 0.585

stats = PasswordStats('V3ryG00dPassw0rd?!')
print(stats.strength())  #-> Its strength is 0.767

Now say you have a use case where you need to create a password policy for testing passwords and say you only want to filter those passwords which scores a strength greater than 0.5, for that you would have to set Password policy with strength 0.50

policy = PasswordPolicy.from_names(
    strength=0.50  # need a password that scores at least 0.5 with its strength
)

Say you have a password which has a score of 0.316 (qwerty123) then the below code would give you Strength value and EntropyBits if it does not match your password policy. (A non empty list)

print(policy.test('qwerty123'))
# [Strength(0.5, 30)]

In case it passes the password policy you would get an empty list, eg

print(policy.test('YCw9qDog8Zn20QD'))             
# []  - good password; it actually scored 0.5
Himanshu Poddar
  • 7,112
  • 10
  • 47
  • 93
0

You have two aspects to consider:

  • the first one is strength, defined as a function of the "entropy bits" value checked against a minimum value which defaults to 30. Since the entropy bits are computed as password_length * log2(alphabet_length) where the alphabet is composed of the distinct chars in the password, you will need at least a 10-chars password with at most one repeated char. 9-char passwords, even with no repetition, will always be "too weak": 9*log(9,2) is just 28.53
  • the second one is the "weakness factor", defined as the lenght of repeating patterns ("blahblah") and/or substrings belonging to sequences ('abcd', '123', 'qwerty') divided by the total password length, and capped to 1.0. So a weakness factor of 1.0 means the whole password has weakness issues, a factor of 0.0 means there are no such issues at all.

Summing up, qwerty123 and m#U0(Bp94 have the same entropy; but the former has a weakness factor of 1.0 and the latter of 0.0.

What can you do:

  • modify the entropy bits threshold:
from password_strength import PasswordStats as pwdstats
stats1=pwdstats('qwerty123')
stats2=pwdstats('m#U0(Bp94')

>>> stats2.strength() #the values here are the same for stats1 and stats2
0.31699249982723876

>>> stats2.strength(weak_bits=20)
0.5386902793854662

>>> stats2.strength(weak_bits=15)
0.694019299386392
  • Combine strength and weakness factor:
>>> (1-stats1.weakness_factor)*stats1.strength(weak_bits=15) #very bad pwd
0.0

>>> (1-stats2.weakness_factor)*stats2.strength(weak_bits=15) #very good pwd
0.694019299386392
gimix
  • 3,431
  • 2
  • 5
  • 21