Safe is a library for checking the strength of passwords.
https://pypi.python.org/pypi/Safe/ https://github.com/lepture/safe
INSTALL
You can install it with pip.
$ pip install safe
For the time being, import safe
.
>>> import safe
You can check the strength with the safe.check ()
function.
>>> safe.check(1)
terrible
>>> safe.check('password')
simple
>>> safe.check('is.safe')
terrible
>>> safe.check('x*V-92Ba')
strong
The return value is an instance of safe.Strength ().
>>> type(safe.check('x*V-92Ba'))
<class 'safe.Strength'>
The result can be converted to bool ().
>>> bool(safe.check('x*V-92Ba'))
True
>>> bool(safe.check('a'))
False
I will read the code.
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L147-L189
The safe.check ()
function checks the strength of the password.
You can pass raw
, length
, freq
, min_types
, and level
as arguments.
raw
is the password string you want to look up. Normally, str is passed, but to_unicode () is done without a function, and even if int is passed, it is converted to str and processed.
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L156
to_unicode () is defined in _compat.py. https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/_compat.py#L28-L38
length
is the required password length. freq
is used to find common passwords.
min_types
specifies how many character types should be included. For example, if min_types = 3 and length = 3, 1qA
is OK (number / lowercase / uppercase) and 1qa
is NG (number / lowercase).
>>> bool(safe.check('1qA', length=3, min_types=3))
True
>>> bool(safe.check('1qa', length=3, min_types=3))
False
level
is the threshold for whether the password strength is valid or not. It seems that int / float is acceptable for the input value, but even if you specify a number greater than or equal to STRONG, it will be returned to STRONG (otherwise it will always be invalid ...).
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L157-L158
The level is defined as follows:
TERRIBLE = 0
SIMPLE = 1
MEDIUM = 2
STRONG = 3
The return value is an instance of safe.Strength
. safe.Strength
has the attributes valid
, strength
, and message
.
valid
is a bool value. True is valid. strength
is a string that indicates strength. The string that goes into strength is one of the following:
String used for strength | meaning |
---|---|
strong | Strong |
medium | Okay |
simple | Easy |
terrible | Nose fucking(Free translation) |
(By the way, this string has been hard-coded in the code when instantiating safe.Strength
orz)
message
is a message that shows why it was judged so.
This function will return the result correctly if you pass a string that gets caught in safe.is_asdf () with one character, for example.
>>> safe.check('a', length=0, min_types=0)
simple
However, if you pass a string that does not get caught in safe.is_asdf () with one character, the exception sent by safe.is_by_step () will be thrown without handling.
>>> safe.check('(', length=0, min_types=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/sximada/ng/env/lib/python3.4/site-packages/safe/__init__.py", line 163, in check
if is_asdf(raw) or is_by_step(raw):
File "/home/sximada/ng/env/lib/python3.4/site-packages/safe/__init__.py", line 89, in is_by_step
delta = ord(raw[1]) - ord(raw[0])
IndexError: string index out of range
This is because the error is not handled correctly at the time of condition check.
safe.is_by_step () will be described later, but when passing a one-character string, an IndexError exception will be thrown. If safe.is_asdf () is a non-True string (for example, (
), then one character (
will be passed to safe.is_by_step ().
if is_asdf(raw) or is_by_step(raw):
return Strength(False, 'simple', 'password has a pattern')
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L163-L164
However, it is rare that one character is allowed to be checked, so I feel that I don't have to be too nervous.
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L72-L83
Determines if the given string is in keyboard order. The sort order here is the character string defined in the next place. https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L69 Therefore, not all keyboard order patterns are inspected. (Isn't it a little too small?)
raw
is the character string to judge. The character string specified by raw
and the character string whose order is reversed are subject to judgment.
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L75
Bool value. Returns True if the keyboard is in the order of the keyboard.
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L86-L95
Shift cryptography is a classic and lovable (but never used) cryptography that shifts by n characters. Among them, the Caesar cipher is famous and shifts by 3 characters. For example, if you shift the string test
by 3 characters, you will get the string whvw
. Such strings are cracked in a blink of an eye, so it just makes you feel like you're hiding it, and it doesn't mean anything.
This function determines whether it is such a character string.
The distance between the 1st and 0th characters of the specified character string raw
is measured.
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L89
After that, it is judged whether all the characters are shifted according to the distance. https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L91-L95
If you pass a string of length 1, IndexError will be sent.
>>> safe.is_by_step('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/sximada/ng/env/lib/python3.4/site-packages/safe/__init__.py", line 89, in is_by_step
delta = ord(raw[1]) - ord(raw[0])
IndexError: string index out of range
raw
is the character string to judge.
The bool value. True if it is a shift cipher string.
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L98-L106
According to the docstring, it says that it uses the common password 1000 at https://xato.net/passwords/more-top-worst-passwords/, but unfortunately this URL was a 404 Not Found ( Hey!!).
A list of commonly used passwords is included in the package. This list is used by default. https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/words.dat
This file has the following format.
String frequency level
Frequent level is an integer used to judge, and the larger the value, the more frequently it is used.
This file can also be a customized file. In that case, if you specify the path of the customized file in the environment variable PYTHON_SAFE_WORDS_FILE
, that will be used.
The data in this file is used as a dict in the form {'string': integer, ...}
when used.
https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L58-L61
After that, the dict is cached, and the location of the cache file can be specified by the environment variable PYTHON_SAFE_WORDS_CACHE
.
This data reads the file when importing the safe package and keeps it in safe.WORDS. https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L68
Therefore, if PYTHON_SAFE_WORDS_FILE
is specified and the file does not exist, FileNotFoundError will be thrown and import will fail (slightly painful specification).
raw
is the character string to judge.
freq
seems to be a commonly used level. The higher the number, the more often it is used.
The bool value. True for commonly used strings. False if the frequency level is less than or equal to the number specified by the argument freq
. It is also False if it does not correspond to a commonly used string.
safe.safety () is a function that just calls safe.check () and returns its return value. The difference between the two is the default value of the argument. safe.check () has a min_type of 3, while safe.safety () has a value of 2. https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L192-L193
But this function is not included in all. And I don't use it inside the package. https://github.com/lepture/safe/blob/cb554022df8be8a4f7fa0b8fbee39639b4819495/safe/init.py#L20-L23 Whether you forgot to include it, or the author's intention to abolish it (I don't want you to do it that way ...), in any case, this function is not used and it is safe. It seems better to use .check (). (By the way, this author writes all fairly well in _compat.py, so it smells like I forgot to write it.)
This library is a small library with only about 200 lines. It was made simple, so it seemed to be very easy to use. I spent about 2 hours writing this article. -> About 100 lines per hour
Recommended Posts