PyOTP 2.2.6__py2.py3-none-any.whl → 2.2.8__py2.py3-none-any.whl

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/__init__.py CHANGED
@@ -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)
pyotp/hotp.py CHANGED
@@ -21,7 +21,7 @@ class HOTP(OTP):
21
21
 
22
22
  def verify(self, otp, counter):
23
23
  """
24
- Verifies the OTP passed in against the current time OTP.
24
+ Verifies the OTP passed in against the current counter OTP.
25
25
 
26
26
  :param otp: the OTP to check against
27
27
  :type otp: str
pyotp/utils.py CHANGED
@@ -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
 
@@ -106,4 +106,4 @@ def strings_equal(s1, s2):
106
106
  """
107
107
  s1 = unicodedata.normalize('NFKC', s1)
108
108
  s2 = unicodedata.normalize('NFKC', s2)
109
- return compare_digest(s1, s2)
109
+ return compare_digest(s1.encode(), s2.encode())
@@ -0,0 +1,21 @@
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
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -1,21 +1,23 @@
1
- Metadata-Version: 2.0
1
+ Metadata-Version: 2.1
2
2
  Name: pyotp
3
- Version: 2.2.6
3
+ Version: 2.2.8
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: BSD License
8
+ License: MIT License
9
9
  Platform: MacOS X
10
10
  Platform: Posix
11
11
  Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: BSD License
12
+ Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Operating System :: MacOS :: MacOS X
14
14
  Classifier: Operating System :: POSIX
15
15
  Classifier: Programming Language :: Python
16
16
  Classifier: Programming Language :: Python :: 2.7
17
- Classifier: Programming Language :: Python :: 3.3
18
17
  Classifier: Programming Language :: Python :: 3.4
18
+ Classifier: Programming Language :: Python :: 3.5
19
+ Classifier: Programming Language :: Python :: 3.6
20
+ Classifier: Programming Language :: Python :: 3.7
19
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
22
 
21
23
  PyOTP - The Python One-Time Password Library
@@ -32,7 +34,27 @@ Authenticator <https://en.wikipedia.org/wiki/Google_Authenticator>`_, `Authy <ht
32
34
  compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
33
35
  <https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
34
36
 
35
- We recommend that implementers read the `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_ and `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of authentication best practices.
37
+ Implementers should read and follow the `HOTP security requirements <https://tools.ietf.org/html/rfc4226#section-7>`_
38
+ and `TOTP security considerations <https://tools.ietf.org/html/rfc6238#section-5>`_ sections of the relevant RFCs. At
39
+ minimum, application implementers should follow this checklist:
40
+
41
+ - Ensure transport confidentiality by using HTTPS
42
+ - Ensure HOTP/TOTP secret confidentiality by storing secrets in a controlled access database
43
+ - Deny replay attacks by rejecting one-time passwords that have been used by the client (this requires storing the most
44
+ recently authenticated timestamp, OTP, or hash of the OTP in your database, and rejecting the OTP when a match is seen)
45
+ - Throttle brute-force attacks against your application's login functionality
46
+ - When implementing a "greenfield" application, consider supporting
47
+ `FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_/`WebAuthn <https://www.w3.org/TR/webauthn/>`_ in
48
+ addition to HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which strengthens your
49
+ MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a dedicated single-purpose
50
+ device, which strengthens your clients against client-side attacks. And by automating scoping of credentials to
51
+ relying party IDs (application origin/domain names), U2F adds protection against phishing attacks. One implementation of
52
+ FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
53
+
54
+ We also recommend that implementers read the
55
+ `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_ and
56
+ `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of
57
+ authentication best practices.
36
58
 
37
59
  Quick overview of using One Time Passwords on your phone
38
60
  --------------------------------------------------------
@@ -56,25 +78,25 @@ Time-based OTPs
56
78
  ::
57
79
 
58
80
  totp = pyotp.TOTP('base32secret3232')
59
- totp.now() # => 492039
81
+ totp.now() # => '492039'
60
82
 
61
83
  # OTP verified for current time
62
- totp.verify(492039) # => True
84
+ totp.verify('492039') # => True
63
85
  time.sleep(30)
64
- totp.verify(492039) # => False
86
+ totp.verify('492039') # => False
65
87
 
66
88
  Counter-based OTPs
67
89
  ~~~~~~~~~~~~~~~~~~
68
90
  ::
69
91
 
70
92
  hotp = pyotp.HOTP('base32secret3232')
71
- hotp.at(0) # => 260182
72
- hotp.at(1) # => 55283
73
- hotp.at(1401) # => 316439
93
+ hotp.at(0) # => '260182'
94
+ hotp.at(1) # => '055283'
95
+ hotp.at(1401) # => '316439'
74
96
 
75
97
  # OTP verified with a counter
76
- hotp.verify(316439, 1401) # => True
77
- hotp.verify(316439, 1402) # => False
98
+ hotp.verify('316439', 1401) # => True
99
+ hotp.verify('316439', 1402) # => False
78
100
 
79
101
  Generating a base32 Secret Key
80
102
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -104,7 +126,7 @@ Working example
104
126
 
105
127
  Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):
106
128
 
107
- .. image:: http://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
129
+ .. image:: https://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
108
130
 
109
131
  Now run the following and compare the output::
110
132
 
@@ -123,9 +145,14 @@ Links
123
145
  * `RFC 6238: TOTP: Time-Based One-Time Password Algorithm <https://tools.ietf.org/html/rfc6238>`_
124
146
  * `ROTP <https://github.com/mdp/rotp>`_ - Original Ruby OTP library by `Mark Percival <https://github.com/mdp>`_
125
147
  * `OTPHP <https://github.com/lelag/otphp>`_ - PHP port of ROTP by `Le Lag <https://github.com/lelag>`_
126
- * `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_
148
+ * `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_
127
149
  * `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_
128
150
 
151
+ For new applications:
152
+
153
+ * `WebAuthn <https://www.w3.org/TR/webauthn/>`_
154
+ * `PyWARP <https://github.com/pyauth/pywarp>`_
155
+
129
156
  .. image:: https://img.shields.io/travis/pyotp/pyotp.svg
130
157
  :target: https://travis-ci.org/pyotp/pyotp
131
158
  .. image:: https://img.shields.io/codecov/c/github/pyotp/pyotp/master.svg
@@ -0,0 +1,11 @@
1
+ pyotp/__init__.py,sha256=hamm6NeVXq0-y6jlBlVnO7oct5n5EHWltinaBxge8xk,685
2
+ pyotp/compat.py,sha256=QVb4buImn4PyP0qe5uLiXsO2-p4ItTGl01Vbt2dILNE,222
3
+ pyotp/hotp.py,sha256=Jotukhsjpwpbx05iHHPYgH0HzpAFUvRAnWauQ_4N69M,1772
4
+ pyotp/otp.py,sha256=QPyHxZ7fY7_zlrMVVveGQrCfn6gatpaHO3-ok9XwCaU,2344
5
+ pyotp/totp.py,sha256=EHnv9irTDDt2cLUIxy3w_80QaqtduAM08Xq7rU2bIm0,3168
6
+ pyotp/utils.py,sha256=smffRHfGU9fwpzmkLrKz6Z3xt07-PEJ2lf8mJ1Tvn7I,3513
7
+ pyotp-2.2.8.dist-info/LICENSE,sha256=f1C5lELlDYN3777_-tBjT7mgRr6HCXrzppnWNwsOG2M,1174
8
+ pyotp-2.2.8.dist-info/METADATA,sha256=OHVMnmqShG3BbmFJPG9C6bi50zdvLZ27XJHr_NOq148,8004
9
+ pyotp-2.2.8.dist-info/WHEEL,sha256=h_aVn5OB2IERUjMbi2pucmR_zzWJtk303YXvhh60NJ8,110
10
+ pyotp-2.2.8.dist-info/top_level.txt,sha256=rFDgz6Sm4nbkYk6tlSRiMcJPyYdnY6LcZiAaYTxVc5k,6
11
+ pyotp-2.2.8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.29.0)
2
+ Generator: bdist_wheel (0.33.4)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -1,120 +0,0 @@
1
- PyOTP - The Python One-Time Password Library
2
- ============================================
3
-
4
- PyOTP is a Python library for generating and verifying one-time passwords. It can be used to implement two-factor (2FA)
5
- or multi-factor (MFA) authentication methods in web applications and in other systems that require users to log in.
6
-
7
- Open MFA standards are defined in `RFC 4226 <https://tools.ietf.org/html/rfc4226>`_ (HOTP: An HMAC-Based One-Time
8
- Password Algorithm) and in `RFC 6238 <https://tools.ietf.org/html/rfc6238>`_ (TOTP: Time-Based One-Time Password
9
- Algorithm). PyOTP implements server-side support for both of these standards. Client-side support can be enabled by
10
- sending authentication codes to users over SMS or email (HOTP) or, for TOTP, by instructing users to use `Google
11
- Authenticator <https://en.wikipedia.org/wiki/Google_Authenticator>`_, `Authy <https://www.authy.com/>`_, or another
12
- compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
13
- <https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
14
-
15
- We recommend that implementers read the `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_ and `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_ for a high level overview of authentication best practices.
16
-
17
- Quick overview of using One Time Passwords on your phone
18
- --------------------------------------------------------
19
-
20
- * OTPs involve a shared secret, stored both on the phone and the server
21
- * OTPs can be generated on a phone without internet connectivity
22
- * OTPs should always be used as a second factor of authentication (if your phone is lost, you account is still secured with a password)
23
- * Google Authenticator and other OTP client apps allow you to store multiple OTP secrets and provision those using a QR Code
24
-
25
- Installation
26
- ------------
27
- ::
28
-
29
- pip install pyotp
30
-
31
- Usage
32
- -----
33
-
34
- Time-based OTPs
35
- ~~~~~~~~~~~~~~~
36
- ::
37
-
38
- totp = pyotp.TOTP('base32secret3232')
39
- totp.now() # => 492039
40
-
41
- # OTP verified for current time
42
- totp.verify(492039) # => True
43
- time.sleep(30)
44
- totp.verify(492039) # => False
45
-
46
- Counter-based OTPs
47
- ~~~~~~~~~~~~~~~~~~
48
- ::
49
-
50
- hotp = pyotp.HOTP('base32secret3232')
51
- hotp.at(0) # => 260182
52
- hotp.at(1) # => 55283
53
- hotp.at(1401) # => 316439
54
-
55
- # OTP verified with a counter
56
- hotp.verify(316439, 1401) # => True
57
- hotp.verify(316439, 1402) # => False
58
-
59
- Generating a base32 Secret Key
60
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61
- ::
62
-
63
- pyotp.random_base32() # returns a 16 character base32 secret. Compatible with Google Authenticator and other OTP apps
64
-
65
- Google Authenticator Compatible
66
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67
-
68
- PyOTP works with the Google Authenticator iPhone and Android app, as well as other OTP apps like Authy. PyOTP includes the
69
- ability to generate provisioning URIs for use with the QR Code scanner built into these MFA client apps::
70
-
71
- pyotp.totp.TOTP('JBSWY3DPEHPK3PXP').provisioning_uri("alice@google.com", issuer_name="Secure App")
72
-
73
- >>> 'otpauth://totp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App'
74
-
75
- pyotp.hotp.HOTP('JBSWY3DPEHPK3PXP').provisioning_uri("alice@google.com", initial_count=0, issuer_name="Secure App")
76
-
77
- >>> 'otpauth://hotp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App&counter=0'
78
-
79
- This URL can then be rendered as a QR Code (for example, using https://github.com/neocotic/qrious) which can then be scanned
80
- and added to the users list of OTP credentials.
81
-
82
- Working example
83
- ~~~~~~~~~~~~~~~
84
-
85
- Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):
86
-
87
- .. image:: http://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
88
-
89
- Now run the following and compare the output::
90
-
91
- import pyotp
92
- totp = pyotp.TOTP("JBSWY3DPEHPK3PXP")
93
- print("Current OTP:", totp.now())
94
-
95
- Links
96
- ~~~~~
97
-
98
- * `Project home page (GitHub) <https://github.com/pyotp/pyotp>`_
99
- * `Documentation (Read the Docs) <https://pyotp.readthedocs.io/en/latest/>`_
100
- * `Package distribution (PyPI) <https://pypi.python.org/pypi/pyotp>`_
101
- * `Change log <https://github.com/pyotp/pyotp/blob/master/Changes.rst>`_
102
- * `RFC 4226: HOTP: An HMAC-Based One-Time Password <https://tools.ietf.org/html/rfc4226>`_
103
- * `RFC 6238: TOTP: Time-Based One-Time Password Algorithm <https://tools.ietf.org/html/rfc6238>`_
104
- * `ROTP <https://github.com/mdp/rotp>`_ - Original Ruby OTP library by `Mark Percival <https://github.com/mdp>`_
105
- * `OTPHP <https://github.com/lelag/otphp>`_ - PHP port of ROTP by `Le Lag <https://github.com/lelag>`_
106
- * `OWASP Authentication Cheat Sheet <https://www.owasp.org/index.php/Authentication_Cheat_Sheet>`_
107
- * `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_
108
-
109
- .. image:: https://img.shields.io/travis/pyotp/pyotp.svg
110
- :target: https://travis-ci.org/pyotp/pyotp
111
- .. image:: https://img.shields.io/codecov/c/github/pyotp/pyotp/master.svg
112
- :target: https://codecov.io/github/pyotp/pyotp?branch=master
113
- .. image:: https://img.shields.io/pypi/v/pyotp.svg
114
- :target: https://pypi.python.org/pypi/pyotp
115
- .. image:: https://img.shields.io/pypi/l/pyotp.svg
116
- :target: https://pypi.python.org/pypi/pyotp
117
- .. image:: https://readthedocs.org/projects/pyotp/badge/?version=latest
118
- :target: https://pyotp.readthedocs.io/
119
-
120
-
@@ -1,12 +0,0 @@
1
- pyotp/__init__.py,sha256=3I4NkdbXw4iHBbtfL7-dbNv8XZn0EUzS0Fc1riI1CJ8,485
2
- pyotp/compat.py,sha256=QVb4buImn4PyP0qe5uLiXsO2-p4ItTGl01Vbt2dILNE,222
3
- pyotp/hotp.py,sha256=IE8W055gBBV1kQv4v7prJ_L58IvZe9mUMIcjF13pyNk,1769
4
- pyotp/otp.py,sha256=QPyHxZ7fY7_zlrMVVveGQrCfn6gatpaHO3-ok9XwCaU,2344
5
- pyotp/totp.py,sha256=EHnv9irTDDt2cLUIxy3w_80QaqtduAM08Xq7rU2bIm0,3168
6
- pyotp/utils.py,sha256=yNbD4BeXUs1mv5muOwxp8dtnaqlBt4NC4ImLSjB6OGQ,3495
7
- pyotp-2.2.6.dist-info/DESCRIPTION.rst,sha256=KI0U6tvZaxBYmlD_VyLpHeyNm5elafwC0eCMmFsfCP0,5471
8
- pyotp-2.2.6.dist-info/METADATA,sha256=ntbqIw2lOH8-JFl68J5Fj2h6GjUjPG2aY0WNBx0FLNk,6167
9
- pyotp-2.2.6.dist-info/RECORD,,
10
- pyotp-2.2.6.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110
11
- pyotp-2.2.6.dist-info/metadata.json,sha256=AFaiADRx4xZYCktiIUacspllTHRVobY-tyltQMD_0Hs,825
12
- pyotp-2.2.6.dist-info/top_level.txt,sha256=rFDgz6Sm4nbkYk6tlSRiMcJPyYdnY6LcZiAaYTxVc5k,6
@@ -1 +0,0 @@
1
- {"classifiers": ["Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Topic :: Software Development :: Libraries :: Python Modules"], "extensions": {"python.details": {"contacts": [{"email": "kislyuk@gmail.com", "name": "PyOTP contributors", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/pyotp/pyotp"}}}, "generator": "bdist_wheel (0.29.0)", "license": "BSD License", "metadata_version": "2.0", "name": "pyotp", "platform": "MacOS X", "summary": "Python One Time Password Library", "version": "2.2.6"}