Zack Williams | 2894e4f | 2020-09-17 09:45:17 -0700 | [diff] [blame^] | 1 | #!/usr/bin/env python3 |
| 2 | # |
| 3 | # SPDX-FileCopyrightText: © 2020 Open Networking Foundation <support@opennetworking.org> |
| 4 | # SPDX-License-Identifier: Apache-2.0 |
| 5 | |
| 6 | # goodpassword.py |
| 7 | |
| 8 | import getpass |
| 9 | import sys |
| 10 | import zxcvbn |
| 11 | from passlib.hash import bcrypt, sha512_crypt |
| 12 | |
| 13 | MIN_LEN = 12 |
| 14 | REQ_SCORE = 4 |
| 15 | |
| 16 | print("goodpassword.py - generates unix password hashes of high quality") |
| 17 | pw = getpass.getpass() |
| 18 | |
| 19 | # reject short passwords |
| 20 | pwlen = len(pw) |
| 21 | if pwlen < MIN_LEN: |
| 22 | print( |
| 23 | "Passwords must be at least %d characters long (the one supplied was %d)." |
| 24 | % (MIN_LEN, pwlen) |
| 25 | ) |
| 26 | sys.exit(1) |
| 27 | |
| 28 | # generate password score |
| 29 | zxscore = zxcvbn.zxcvbn(pw) |
| 30 | |
| 31 | # Print any suggestions |
| 32 | if zxscore["feedback"]["warning"]: |
| 33 | print("Warning: %s" % zxscore["feedback"]["warning"]) |
| 34 | |
| 35 | if zxscore["feedback"]["suggestions"]: |
| 36 | print("Suggestions:") |
| 37 | for suggestion in zxscore["feedback"]["suggestions"]: |
| 38 | print(" - %s" % suggestion) |
| 39 | |
| 40 | print( |
| 41 | "This password had a complexity score of %d (must score at least %d)" |
| 42 | % (zxscore["score"], REQ_SCORE) |
| 43 | ) |
| 44 | |
| 45 | print( |
| 46 | "Time to crack: %s" |
| 47 | % zxscore["crack_times_display"]["offline_slow_hashing_1e4_per_second"] |
| 48 | ) |
| 49 | |
| 50 | years = 5 |
| 51 | min_crack_seconds = 60 * 60 * 24 * 365 * years # number of seconds per year |
| 52 | # if the password crack time is too short |
| 53 | if ( |
| 54 | zxscore["crack_times_seconds"]["offline_slow_hashing_1e4_per_second"] |
| 55 | < min_crack_seconds |
| 56 | ): |
| 57 | print( |
| 58 | "This password was crackable in less than %d years, please make it longer/more complex" |
| 59 | % years |
| 60 | ) |
| 61 | sys.exit(1) |
| 62 | |
| 63 | # if the password score is too low |
| 64 | if zxscore["score"] < REQ_SCORE: |
| 65 | sys.exit(1) |
| 66 | |
| 67 | # password is high enough quality |
| 68 | # this make take a short while so let the user know |
| 69 | print("Generating password hashes...") |
| 70 | print('bcrypt: "%s"' % bcrypt.using(rounds=16).hash(pw)) |
| 71 | print('sha512crypt: "%s"' % sha512_crypt.hash(pw)) |