Updates
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: pyotp
|
||||
Version: 2.9.0
|
||||
Summary: Python One Time Password Library
|
||||
Home-page: https://github.com/pyotp/pyotp
|
||||
Author: PyOTP contributors
|
||||
Author-email: kislyuk@gmail.com
|
||||
License: MIT License
|
||||
Project-URL: Documentation, https://pyauth.github.io/pyotp
|
||||
Project-URL: Source Code, https://github.com/pyauth/pyotp
|
||||
Project-URL: Issue Tracker, https://github.com/pyauth/pyotp/issues
|
||||
Project-URL: Change Log, https://github.com/pyauth/pyotp/blob/master/Changes.rst
|
||||
Platform: MacOS X
|
||||
Platform: Posix
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Operating System :: MacOS :: MacOS X
|
||||
Classifier: Operating System :: POSIX
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: Programming Language :: Python :: 3.11
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Requires-Python: >=3.7
|
||||
License-File: LICENSE
|
||||
Provides-Extra: test
|
||||
Requires-Dist: coverage ; extra == 'test'
|
||||
Requires-Dist: wheel ; extra == 'test'
|
||||
Requires-Dist: ruff ; extra == 'test'
|
||||
Requires-Dist: mypy ; extra == 'test'
|
||||
|
||||
PyOTP - The Python One-Time Password Library
|
||||
============================================
|
||||
|
||||
PyOTP is a Python library for generating and verifying one-time passwords. It can be used to implement two-factor (2FA)
|
||||
or multi-factor (MFA) authentication methods in web applications and in other systems that require users to log in.
|
||||
|
||||
Open MFA standards are defined in `RFC 4226 <https://tools.ietf.org/html/rfc4226>`_ (HOTP: An HMAC-Based One-Time
|
||||
Password Algorithm) and in `RFC 6238 <https://tools.ietf.org/html/rfc6238>`_ (TOTP: Time-Based One-Time Password
|
||||
Algorithm). PyOTP implements server-side support for both of these standards. Client-side support can be enabled by
|
||||
sending authentication codes to users over SMS or email (HOTP) or, for TOTP, by instructing users to use `Google
|
||||
Authenticator <https://en.wikipedia.org/wiki/Google_Authenticator>`_, `Authy <https://www.authy.com/>`_, or another
|
||||
compatible app. Users can set up auth tokens in their apps easily by using their phone camera to scan `otpauth://
|
||||
<https://github.com/google/google-authenticator/wiki/Key-Uri-Format>`_ QR codes provided by PyOTP.
|
||||
|
||||
Implementers should read and follow the `HOTP security requirements <https://tools.ietf.org/html/rfc4226#section-7>`_
|
||||
and `TOTP security considerations <https://tools.ietf.org/html/rfc6238#section-5>`_ sections of the relevant RFCs. At
|
||||
minimum, application implementers should follow this checklist:
|
||||
|
||||
- Ensure transport confidentiality by using HTTPS
|
||||
- Ensure HOTP/TOTP secret confidentiality by storing secrets in a controlled access database
|
||||
- Deny replay attacks by rejecting one-time passwords that have been used by the client (this requires storing the most
|
||||
recently authenticated timestamp, OTP, or hash of the OTP in your database, and rejecting the OTP when a match is
|
||||
seen)
|
||||
- Throttle (rate limit) brute-force attacks against your application's login functionality (see RFC 4226, section 7.3)
|
||||
- When implementing a "greenfield" application, consider supporting
|
||||
`FIDO U2F <https://en.wikipedia.org/wiki/Universal_2nd_Factor>`_/`WebAuthn <https://www.w3.org/TR/webauthn/>`_ in
|
||||
addition to HOTP/TOTP. U2F uses asymmetric cryptography to avoid using a shared secret design, which strengthens your
|
||||
MFA solution against server-side attacks. Hardware U2F also sequesters the client secret in a dedicated single-purpose
|
||||
device, which strengthens your clients against client-side attacks. And by automating scoping of credentials to
|
||||
relying party IDs (application origin/domain names), U2F adds protection against phishing attacks. One implementation
|
||||
of FIDO U2F/WebAuthn is PyOTP's sister project, `PyWARP <https://github.com/pyauth/pywarp>`_.
|
||||
|
||||
We also recommend that implementers read the
|
||||
`OWASP Authentication Cheat Sheet
|
||||
<https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_ 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.
|
||||
|
||||
Quick overview of using One Time Passwords on your phone
|
||||
--------------------------------------------------------
|
||||
|
||||
* OTPs involve a shared secret, stored both on the phone and the server
|
||||
* OTPs can be generated on a phone without internet connectivity
|
||||
* OTPs should always be used as a second factor of authentication (if your phone is lost, you account is still secured
|
||||
with a password)
|
||||
* Google Authenticator and other OTP client apps allow you to store multiple OTP secrets and provision those using a QR
|
||||
Code
|
||||
|
||||
Installation
|
||||
------------
|
||||
::
|
||||
|
||||
pip install pyotp
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Time-based OTPs
|
||||
~~~~~~~~~~~~~~~
|
||||
::
|
||||
|
||||
import pyotp
|
||||
import time
|
||||
|
||||
totp = pyotp.TOTP('base32secret3232')
|
||||
totp.now() # => '492039'
|
||||
|
||||
# OTP verified for current time
|
||||
totp.verify('492039') # => True
|
||||
time.sleep(30)
|
||||
totp.verify('492039') # => False
|
||||
|
||||
Counter-based OTPs
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
::
|
||||
|
||||
import pyotp
|
||||
|
||||
hotp = pyotp.HOTP('base32secret3232')
|
||||
hotp.at(0) # => '260182'
|
||||
hotp.at(1) # => '055283'
|
||||
hotp.at(1401) # => '316439'
|
||||
|
||||
# OTP verified with a counter
|
||||
hotp.verify('316439', 1401) # => True
|
||||
hotp.verify('316439', 1402) # => False
|
||||
|
||||
Generating a Secret Key
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
A helper function is provided to generate a 32-character base32 secret, compatible with Google Authenticator and other
|
||||
OTP apps::
|
||||
|
||||
pyotp.random_base32()
|
||||
|
||||
Some applications want the secret key to be formatted as a hex-encoded string::
|
||||
|
||||
pyotp.random_hex() # returns a 40-character hex-encoded secret
|
||||
|
||||
Google Authenticator Compatible
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
PyOTP works with the Google Authenticator iPhone and Android app, as well as other OTP apps like Authy. PyOTP includes
|
||||
the ability to generate provisioning URIs for use with the QR Code scanner built into these MFA client apps::
|
||||
|
||||
pyotp.totp.TOTP('JBSWY3DPEHPK3PXP').provisioning_uri(name='alice@google.com', issuer_name='Secure App')
|
||||
|
||||
>>> 'otpauth://totp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App'
|
||||
|
||||
pyotp.hotp.HOTP('JBSWY3DPEHPK3PXP').provisioning_uri(name="alice@google.com", issuer_name="Secure App", initial_count=0)
|
||||
|
||||
>>> 'otpauth://hotp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App&counter=0'
|
||||
|
||||
This URL can then be rendered as a QR Code (for example, using https://github.com/soldair/node-qrcode) which can then be
|
||||
scanned and added to the users list of OTP credentials.
|
||||
|
||||
Parsing these URLs is also supported::
|
||||
|
||||
pyotp.parse_uri('otpauth://totp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App')
|
||||
|
||||
>>> <pyotp.totp.TOTP object at 0xFFFFFFFF>
|
||||
|
||||
pyotp.parse_uri('otpauth://hotp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App&counter=0'
|
||||
|
||||
>>> <pyotp.totp.HOTP object at 0xFFFFFFFF>
|
||||
|
||||
Working example
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Scan the following barcode with your phone's OTP app (e.g. Google Authenticator):
|
||||
|
||||
.. image:: https://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP
|
||||
|
||||
Now run the following and compare the output::
|
||||
|
||||
import pyotp
|
||||
totp = pyotp.TOTP("JBSWY3DPEHPK3PXP")
|
||||
print("Current OTP:", totp.now())
|
||||
|
||||
Third-party contributions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The following third-party contributions are not described by a standard, not officially supported, and provided for
|
||||
reference only:
|
||||
|
||||
* ``pyotp.contrib.Steam()``: An implementation of Steam TOTP. Uses the same API as `pyotp.TOTP()`.
|
||||
|
||||
Links
|
||||
~~~~~
|
||||
|
||||
* `Project home page (GitHub) <https://github.com/pyauth/pyotp>`_
|
||||
* `Documentation <https://pyauth.github.io/pyotp/>`_
|
||||
* `Package distribution (PyPI) <https://pypi.python.org/pypi/pyotp>`_
|
||||
* `Change log <https://github.com/pyauth/pyotp/blob/master/Changes.rst>`_
|
||||
* `RFC 4226: HOTP: An HMAC-Based One-Time Password <https://tools.ietf.org/html/rfc4226>`_
|
||||
* `RFC 6238: TOTP: Time-Based One-Time Password Algorithm <https://tools.ietf.org/html/rfc6238>`_
|
||||
* `ROTP <https://github.com/mdp/rotp>`_ - Original Ruby OTP library by `Mark Percival <https://github.com/mdp>`_
|
||||
* `OTPHP <https://github.com/lelag/otphp>`_ - PHP port of ROTP by `Le Lag <https://github.com/lelag>`_
|
||||
* `OWASP Authentication Cheat Sheet <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md>`_
|
||||
* `NIST SP 800-63-3: Digital Authentication Guideline <https://pages.nist.gov/800-63-3/>`_
|
||||
|
||||
For new applications:
|
||||
|
||||
* `WebAuthn <https://www.w3.org/TR/webauthn/>`_
|
||||
* `PyWARP <https://github.com/pyauth/pywarp>`_
|
||||
|
||||
Versioning
|
||||
~~~~~~~~~~
|
||||
This package follows the `Semantic Versioning 2.0.0 <http://semver.org/>`_ standard. To control changes, it is
|
||||
recommended that application developers pin the package version and manage it using `pip-tools
|
||||
<https://github.com/jazzband/pip-tools>`_ or similar. For library developers, pinning the major version is
|
||||
recommended.
|
||||
|
||||
.. image:: https://github.com/pyauth/pyotp/workflows/Python%20package/badge.svg
|
||||
:target: https://github.com/pyauth/pyotp/actions
|
||||
.. image:: https://img.shields.io/codecov/c/github/pyauth/pyotp/master.svg
|
||||
:target: https://codecov.io/github/pyauth/pyotp?branch=master
|
||||
.. image:: https://img.shields.io/pypi/v/pyotp.svg
|
||||
:target: https://pypi.python.org/pypi/pyotp
|
||||
.. image:: https://img.shields.io/pypi/l/pyotp.svg
|
||||
:target: https://pypi.python.org/pypi/pyotp
|
||||
.. image:: https://readthedocs.org/projects/pyotp/badge/?version=latest
|
||||
:target: https://pyotp.readthedocs.io/
|
||||
Reference in New Issue
Block a user