Skip to content

Commit

Permalink
use the zxcvbn package to estimate password cracking times
Browse files Browse the repository at this point in the history
  • Loading branch information
chr-peters committed Mar 20, 2021
1 parent a51b971 commit 6326998
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 3 deletions.
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ werkzeug==1.0.1
# via flask
whitenoise==5.2.0
# via strong-but-simple-passwords (setup.py)
zxcvbn==4.4.28
# via strong-but-simple-passwords (setup.py)

# The following packages are considered to be unsafe in a requirements file:
# setuptools
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"whitenoise",
"brotli",
"gunicorn",
"zxcvbn",
],
)
11 changes: 11 additions & 0 deletions strong_but_simple_passwords/core.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import random
from zxcvbn import zxcvbn


sentences = [
"My favourite food is ice cream",
Expand Down Expand Up @@ -60,3 +62,12 @@ def generate_password_from_sentence(sentence, letters_per_word=1):

# convert the list of words with the symbol to a single string
return "".join(words_with_symbol)


def get_cracking_time_as_string(password):
"""
Returns the time an attacker needs to crack the password if
the attacker can try 1e4 hashes per second.
"""
result = zxcvbn(password)
return result["crack_times_display"]["offline_slow_hashing_1e4_per_second"]
2 changes: 2 additions & 0 deletions strong_but_simple_passwords/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ <h3>3. Put a random symbol somewhere in between</h3>
{% if generated_password is defined %}
Congratulations! 🎉🎉🎉 You successfully generated a secure password:
{{ generated_password }}
If a hacker tried 10,000 paswords every second, this is how long it would take him to find yours: {{
cracking_time }}
{% endif %}
</main>
</body>
Expand Down
19 changes: 16 additions & 3 deletions strong_but_simple_passwords/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from flask import render_template, request
from .core import get_random_sentence, generate_password_from_sentence
from .core import (
get_random_sentence,
generate_password_from_sentence,
get_cracking_time_as_string,
)


def index():
Expand All @@ -14,8 +18,17 @@ def index():

# read user sentence and generate password
user_sentence = request.form["input_sentence"]
generated_password = generate_password_from_sentence(user_sentence)
generated_password = generate_password_from_sentence(
user_sentence, letters_per_word=3
)

# get the time it would take an offline attacker (1e4 hashes per second)
# to crack this password
cracking_time = get_cracking_time_as_string(generated_password)

return render_template(
"index.html", sentence=user_sentence, generated_password=generated_password
"index.html",
sentence=user_sentence,
generated_password=generated_password,
cracking_time=cracking_time,
)
9 changes: 9 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
get_first_letters_from_each_word,
put_symbol_between_words,
generate_password_from_sentence,
get_cracking_time_as_string,
)
from strong_but_simple_passwords import core
import random
Expand Down Expand Up @@ -119,3 +120,11 @@ def test_generate_password_from_sentence(monkeypatch):
generate_password_from_sentence(sentence, letters_per_word=3)
== "Ilikcut!dogandcat"
)


def test_get_cracking_time_as_string():
"""
This example is taken from the zxcvbn documentation.
"""
password = "JohnSmith123"
assert get_cracking_time_as_string(password) == "4 minutes"

0 comments on commit 6326998

Please sign in to comment.