PyOTP 2.2.6__tar.gz → 2.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyotp-2.2.6 → pyotp-2.2.7}/LICENSE +3 -2
- {pyotp-2.2.6/src/pyotp.egg-info → pyotp-2.2.7}/PKG-INFO +30 -12
- {pyotp-2.2.6 → pyotp-2.2.7}/README.rst +27 -9
- {pyotp-2.2.6 → pyotp-2.2.7}/setup.cfg +1 -1
- {pyotp-2.2.6 → pyotp-2.2.7}/setup.py +3 -3
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp/__init__.py +10 -4
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp/hotp.py +1 -1
- {pyotp-2.2.6 → pyotp-2.2.7/src/pyotp.egg-info}/PKG-INFO +30 -12
- {pyotp-2.2.6 → pyotp-2.2.7}/MANIFEST.in +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/requirements.txt +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp/compat.py +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp/otp.py +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp/totp.py +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp/utils.py +1 -1
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp.egg-info/SOURCES.txt +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp.egg-info/dependency_links.txt +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp.egg-info/not-zip-safe +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/src/pyotp.egg-info/top_level.txt +0 -0
- {pyotp-2.2.6 → pyotp-2.2.7}/test.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
Copyright (C) 2011-
|
|
2
|
-
Nathan Reynolds <email@nreynolds.co.uk>,
|
|
1
|
+
Copyright (C) 2011-2017 Mark Percival <m@mdp.im>,
|
|
2
|
+
Nathan Reynolds <email@nreynolds.co.uk>, Andrey Kislyuk <kislyuk@gmail.com>,
|
|
3
|
+
and PyOTP contributors
|
|
3
4
|
|
|
4
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 1.1
|
|
2
2
|
Name: pyotp
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.7
|
|
4
4
|
Summary: Python One Time Password Library
|
|
5
5
|
Home-page: https://github.com/pyotp/pyotp
|
|
6
6
|
Author: PyOTP contributors
|
|
7
7
|
Author-email: kislyuk@gmail.com
|
|
8
|
-
License:
|
|
8
|
+
License: MIT License
|
|
9
9
|
Description: PyOTP - The Python One-Time Password Library
|
|
10
10
|
============================================
|
|
11
11
|
|
|
@@ -20,7 +20,25 @@ Description: PyOTP - The Python One-Time Password Library
|
|
|
20
20
|
compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
|
|
21
21
|
<https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Implementers should read and follow the `HOTP security requirements <https://tools.ietf.org/html/rfc4226#section-7>`_
|
|
24
|
+
and `TOTP security considerations <https://tools.ietf.org/html/rfc6238#section-5>`_ sections of the relevant RFCs. At
|
|
25
|
+
minimum, application implementers should follow this checklist:
|
|
26
|
+
|
|
27
|
+
- Ensure transport confidentiality by using HTTPS
|
|
28
|
+
- Ensure HOTP/TOTP secret confidentiality by storing secrets in a controlled access database
|
|
29
|
+
- Deny replay attacks by rejecting one-time passwords that have been used by the client (this requires storing the most
|
|
30
|
+
recently authenticated timestamp, OTP, or hash of the OTP in your database, and rejecting the OTP when a match is seen)
|
|
31
|
+
- Throttle brute-force attacks against your application's login functionality
|
|
32
|
+
- When implementing a "green field" application, consider supporting
|
|
33
|
+
`FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_ in addition to HOTP/TOTP. U2F uses asymmetric
|
|
34
|
+
cryptography to avoid using a shared secret design, which strengthens your MFA solution against server-side compromise.
|
|
35
|
+
Hardware U2F also sequesters the client secret in a dedicated single-purpose device, which strengthens your clients
|
|
36
|
+
against client-side compromise.
|
|
37
|
+
|
|
38
|
+
We also recommend that implementers read the
|
|
39
|
+
`OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_ and
|
|
40
|
+
`NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of
|
|
41
|
+
authentication best practices.
|
|
24
42
|
|
|
25
43
|
Quick overview of using One Time Passwords on your phone
|
|
26
44
|
--------------------------------------------------------
|
|
@@ -44,25 +62,25 @@ Description: PyOTP - The Python One-Time Password Library
|
|
|
44
62
|
::
|
|
45
63
|
|
|
46
64
|
totp = pyotp.TOTP('base32secret3232')
|
|
47
|
-
totp.now() # => 492039
|
|
65
|
+
totp.now() # => '492039'
|
|
48
66
|
|
|
49
67
|
# OTP verified for current time
|
|
50
|
-
totp.verify(492039) # => True
|
|
68
|
+
totp.verify('492039') # => True
|
|
51
69
|
time.sleep(30)
|
|
52
|
-
totp.verify(492039) # => False
|
|
70
|
+
totp.verify('492039') # => False
|
|
53
71
|
|
|
54
72
|
Counter-based OTPs
|
|
55
73
|
~~~~~~~~~~~~~~~~~~
|
|
56
74
|
::
|
|
57
75
|
|
|
58
76
|
hotp = pyotp.HOTP('base32secret3232')
|
|
59
|
-
hotp.at(0) # => 260182
|
|
60
|
-
hotp.at(1) # =>
|
|
61
|
-
hotp.at(1401) # => 316439
|
|
77
|
+
hotp.at(0) # => '260182'
|
|
78
|
+
hotp.at(1) # => '055283'
|
|
79
|
+
hotp.at(1401) # => '316439'
|
|
62
80
|
|
|
63
81
|
# OTP verified with a counter
|
|
64
|
-
hotp.verify(316439, 1401) # => True
|
|
65
|
-
hotp.verify(316439, 1402) # => False
|
|
82
|
+
hotp.verify('316439', 1401) # => True
|
|
83
|
+
hotp.verify('316439', 1402) # => False
|
|
66
84
|
|
|
67
85
|
Generating a base32 Secret Key
|
|
68
86
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -128,7 +146,7 @@ Description: PyOTP - The Python One-Time Password Library
|
|
|
128
146
|
Platform: MacOS X
|
|
129
147
|
Platform: Posix
|
|
130
148
|
Classifier: Intended Audience :: Developers
|
|
131
|
-
Classifier: License :: OSI Approved ::
|
|
149
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
132
150
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
133
151
|
Classifier: Operating System :: POSIX
|
|
134
152
|
Classifier: Programming Language :: Python
|
|
@@ -12,7 +12,25 @@ Authenticator <https://en.wikipedia.org/wiki/Google_Authenticator>`_, `Authy <ht
|
|
|
12
12
|
compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
|
|
13
13
|
<https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Implementers should read and follow the `HOTP security requirements <https://tools.ietf.org/html/rfc4226#section-7>`_
|
|
16
|
+
and `TOTP security considerations <https://tools.ietf.org/html/rfc6238#section-5>`_ sections of the relevant RFCs. At
|
|
17
|
+
minimum, application implementers should follow this checklist:
|
|
18
|
+
|
|
19
|
+
- Ensure transport confidentiality by using HTTPS
|
|
20
|
+
- Ensure HOTP/TOTP secret confidentiality by storing secrets in a controlled access database
|
|
21
|
+
- Deny replay attacks by rejecting one-time passwords that have been used by the client (this requires storing the most
|
|
22
|
+
recently authenticated timestamp, OTP, or hash of the OTP in your database, and rejecting the OTP when a match is seen)
|
|
23
|
+
- Throttle brute-force attacks against your application's login functionality
|
|
24
|
+
- When implementing a "green field" application, consider supporting
|
|
25
|
+
`FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_ in addition to HOTP/TOTP. U2F uses asymmetric
|
|
26
|
+
cryptography to avoid using a shared secret design, which strengthens your MFA solution against server-side compromise.
|
|
27
|
+
Hardware U2F also sequesters the client secret in a dedicated single-purpose device, which strengthens your clients
|
|
28
|
+
against client-side compromise.
|
|
29
|
+
|
|
30
|
+
We also recommend that implementers read the
|
|
31
|
+
`OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_ and
|
|
32
|
+
`NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of
|
|
33
|
+
authentication best practices.
|
|
16
34
|
|
|
17
35
|
Quick overview of using One Time Passwords on your phone
|
|
18
36
|
--------------------------------------------------------
|
|
@@ -36,25 +54,25 @@ Time-based OTPs
|
|
|
36
54
|
::
|
|
37
55
|
|
|
38
56
|
totp = pyotp.TOTP('base32secret3232')
|
|
39
|
-
totp.now() # => 492039
|
|
57
|
+
totp.now() # => '492039'
|
|
40
58
|
|
|
41
59
|
# OTP verified for current time
|
|
42
|
-
totp.verify(492039) # => True
|
|
60
|
+
totp.verify('492039') # => True
|
|
43
61
|
time.sleep(30)
|
|
44
|
-
totp.verify(492039) # => False
|
|
62
|
+
totp.verify('492039') # => False
|
|
45
63
|
|
|
46
64
|
Counter-based OTPs
|
|
47
65
|
~~~~~~~~~~~~~~~~~~
|
|
48
66
|
::
|
|
49
67
|
|
|
50
68
|
hotp = pyotp.HOTP('base32secret3232')
|
|
51
|
-
hotp.at(0) # => 260182
|
|
52
|
-
hotp.at(1) # =>
|
|
53
|
-
hotp.at(1401) # => 316439
|
|
69
|
+
hotp.at(0) # => '260182'
|
|
70
|
+
hotp.at(1) # => '055283'
|
|
71
|
+
hotp.at(1401) # => '316439'
|
|
54
72
|
|
|
55
73
|
# OTP verified with a counter
|
|
56
|
-
hotp.verify(316439, 1401) # => True
|
|
57
|
-
hotp.verify(316439, 1402) # => False
|
|
74
|
+
hotp.verify('316439', 1401) # => True
|
|
75
|
+
hotp.verify('316439', 1402) # => False
|
|
58
76
|
|
|
59
77
|
Generating a base32 Secret Key
|
|
60
78
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -7,9 +7,9 @@ install_requires = [line.rstrip() for line in open(os.path.join(os.path.dirname(
|
|
|
7
7
|
|
|
8
8
|
setup(
|
|
9
9
|
name="pyotp",
|
|
10
|
-
version="2.2.
|
|
10
|
+
version="2.2.7",
|
|
11
11
|
url="https://github.com/pyotp/pyotp",
|
|
12
|
-
license="
|
|
12
|
+
license="MIT License",
|
|
13
13
|
author="PyOTP contributors",
|
|
14
14
|
author_email="kislyuk@gmail.com",
|
|
15
15
|
description="Python One Time Password Library",
|
|
@@ -22,7 +22,7 @@ setup(
|
|
|
22
22
|
test_suite="test",
|
|
23
23
|
classifiers=[
|
|
24
24
|
"Intended Audience :: Developers",
|
|
25
|
-
"License :: OSI Approved ::
|
|
25
|
+
"License :: OSI Approved :: MIT License",
|
|
26
26
|
"Operating System :: MacOS :: MacOS X",
|
|
27
27
|
"Operating System :: POSIX",
|
|
28
28
|
"Programming Language :: Python",
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
from __future__ import (absolute_import, division,
|
|
2
2
|
print_function, unicode_literals)
|
|
3
3
|
|
|
4
|
-
import random as _random
|
|
5
|
-
|
|
6
4
|
from pyotp.hotp import HOTP # noqa
|
|
7
5
|
from pyotp.otp import OTP # noqa
|
|
8
6
|
from pyotp.totp import TOTP # noqa
|
|
9
7
|
from . import utils # noqa
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
def random_base32(length=16, random=_random.SystemRandom(),
|
|
9
|
+
def random_base32(length=16, random=None,
|
|
13
10
|
chars=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')):
|
|
11
|
+
|
|
12
|
+
# Use secrets module if available (Python version >= 3.6) per PEP 506
|
|
13
|
+
try:
|
|
14
|
+
import secrets
|
|
15
|
+
random = secrets.SystemRandom()
|
|
16
|
+
except ImportError:
|
|
17
|
+
import random as _random
|
|
18
|
+
random = _random.SystemRandom()
|
|
19
|
+
|
|
14
20
|
return ''.join(
|
|
15
21
|
random.choice(chars)
|
|
16
22
|
for _ in range(length)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 1.1
|
|
2
2
|
Name: pyotp
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.7
|
|
4
4
|
Summary: Python One Time Password Library
|
|
5
5
|
Home-page: https://github.com/pyotp/pyotp
|
|
6
6
|
Author: PyOTP contributors
|
|
7
7
|
Author-email: kislyuk@gmail.com
|
|
8
|
-
License:
|
|
8
|
+
License: MIT License
|
|
9
9
|
Description: PyOTP - The Python One-Time Password Library
|
|
10
10
|
============================================
|
|
11
11
|
|
|
@@ -20,7 +20,25 @@ Description: PyOTP - The Python One-Time Password Library
|
|
|
20
20
|
compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
|
|
21
21
|
<https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Implementers should read and follow the `HOTP security requirements <https://tools.ietf.org/html/rfc4226#section-7>`_
|
|
24
|
+
and `TOTP security considerations <https://tools.ietf.org/html/rfc6238#section-5>`_ sections of the relevant RFCs. At
|
|
25
|
+
minimum, application implementers should follow this checklist:
|
|
26
|
+
|
|
27
|
+
- Ensure transport confidentiality by using HTTPS
|
|
28
|
+
- Ensure HOTP/TOTP secret confidentiality by storing secrets in a controlled access database
|
|
29
|
+
- Deny replay attacks by rejecting one-time passwords that have been used by the client (this requires storing the most
|
|
30
|
+
recently authenticated timestamp, OTP, or hash of the OTP in your database, and rejecting the OTP when a match is seen)
|
|
31
|
+
- Throttle brute-force attacks against your application's login functionality
|
|
32
|
+
- When implementing a "green field" application, consider supporting
|
|
33
|
+
`FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_ in addition to HOTP/TOTP. U2F uses asymmetric
|
|
34
|
+
cryptography to avoid using a shared secret design, which strengthens your MFA solution against server-side compromise.
|
|
35
|
+
Hardware U2F also sequesters the client secret in a dedicated single-purpose device, which strengthens your clients
|
|
36
|
+
against client-side compromise.
|
|
37
|
+
|
|
38
|
+
We also recommend that implementers read the
|
|
39
|
+
`OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_ and
|
|
40
|
+
`NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of
|
|
41
|
+
authentication best practices.
|
|
24
42
|
|
|
25
43
|
Quick overview of using One Time Passwords on your phone
|
|
26
44
|
--------------------------------------------------------
|
|
@@ -44,25 +62,25 @@ Description: PyOTP - The Python One-Time Password Library
|
|
|
44
62
|
::
|
|
45
63
|
|
|
46
64
|
totp = pyotp.TOTP('base32secret3232')
|
|
47
|
-
totp.now() # => 492039
|
|
65
|
+
totp.now() # => '492039'
|
|
48
66
|
|
|
49
67
|
# OTP verified for current time
|
|
50
|
-
totp.verify(492039) # => True
|
|
68
|
+
totp.verify('492039') # => True
|
|
51
69
|
time.sleep(30)
|
|
52
|
-
totp.verify(492039) # => False
|
|
70
|
+
totp.verify('492039') # => False
|
|
53
71
|
|
|
54
72
|
Counter-based OTPs
|
|
55
73
|
~~~~~~~~~~~~~~~~~~
|
|
56
74
|
::
|
|
57
75
|
|
|
58
76
|
hotp = pyotp.HOTP('base32secret3232')
|
|
59
|
-
hotp.at(0) # => 260182
|
|
60
|
-
hotp.at(1) # =>
|
|
61
|
-
hotp.at(1401) # => 316439
|
|
77
|
+
hotp.at(0) # => '260182'
|
|
78
|
+
hotp.at(1) # => '055283'
|
|
79
|
+
hotp.at(1401) # => '316439'
|
|
62
80
|
|
|
63
81
|
# OTP verified with a counter
|
|
64
|
-
hotp.verify(316439, 1401) # => True
|
|
65
|
-
hotp.verify(316439, 1402) # => False
|
|
82
|
+
hotp.verify('316439', 1401) # => True
|
|
83
|
+
hotp.verify('316439', 1402) # => False
|
|
66
84
|
|
|
67
85
|
Generating a base32 Secret Key
|
|
68
86
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -128,7 +146,7 @@ Description: PyOTP - The Python One-Time Password Library
|
|
|
128
146
|
Platform: MacOS X
|
|
129
147
|
Platform: Posix
|
|
130
148
|
Classifier: Intended Audience :: Developers
|
|
131
|
-
Classifier: License :: OSI Approved ::
|
|
149
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
132
150
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
133
151
|
Classifier: Operating System :: POSIX
|
|
134
152
|
Classifier: Programming Language :: Python
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -85,12 +85,12 @@ def _compare_digest(s1, s2):
|
|
|
85
85
|
differences |= ord(c1) ^ ord(c2)
|
|
86
86
|
return differences == 0
|
|
87
87
|
|
|
88
|
+
|
|
88
89
|
try:
|
|
89
90
|
# Python 3.3+ and 2.7.7+ include a timing-attack-resistant
|
|
90
91
|
# comparison function, which is probably more reliable than ours.
|
|
91
92
|
# Use it if available.
|
|
92
93
|
from hmac import compare_digest
|
|
93
|
-
|
|
94
94
|
except ImportError:
|
|
95
95
|
compare_digest = _compare_digest
|
|
96
96
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|