|
Server : LiteSpeed System : Linux srv104790275 5.15.0-161-generic #171-Ubuntu SMP Sat Oct 11 08:17:01 UTC 2025 x86_64 User : dewac4139 ( 1077) PHP Version : 8.0.30 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /usr/local/CyberPanel/lib/python3.10/site-packages/pyotp/ |
Upload File : |
import base64
import hashlib
import hmac
from typing import Any, Optional
class OTP(object):
"""
Base class for OTP handlers.
"""
def __init__(
self,
s: str,
digits: int = 6,
digest: Any = hashlib.sha1,
name: Optional[str] = None,
issuer: Optional[str] = None,
) -> None:
self.digits = digits
if digits > 10:
raise ValueError("digits must be no greater than 10")
self.digest = digest
self.secret = s
self.name = name or "Secret"
self.issuer = issuer
def generate_otp(self, input: int) -> str:
"""
:param input: the HMAC counter value to use as the OTP input.
Usually either the counter, or the computed integer based on the Unix timestamp
"""
if input < 0:
raise ValueError("input must be positive integer")
hasher = hmac.new(self.byte_secret(), self.int_to_bytestring(input), self.digest)
hmac_hash = bytearray(hasher.digest())
offset = hmac_hash[-1] & 0xF
code = (
(hmac_hash[offset] & 0x7F) << 24
| (hmac_hash[offset + 1] & 0xFF) << 16
| (hmac_hash[offset + 2] & 0xFF) << 8
| (hmac_hash[offset + 3] & 0xFF)
)
str_code = str(10_000_000_000 + (code % 10**self.digits))
return str_code[-self.digits :]
def byte_secret(self) -> bytes:
secret = self.secret
missing_padding = len(secret) % 8
if missing_padding != 0:
secret += "=" * (8 - missing_padding)
return base64.b32decode(secret, casefold=True)
@staticmethod
def int_to_bytestring(i: int, padding: int = 8) -> bytes:
"""
Turns an integer to the OATH specified
bytestring, which is fed to the HMAC
along with the secret
"""
result = bytearray()
while i != 0:
result.append(i & 0xFF)
i >>= 8
# It's necessary to convert the final result from bytearray to bytes
# because the hmac functions in python 2.6 and 3.3 don't work with
# bytearray
return bytes(bytearray(reversed(result)).rjust(padding, b"\0"))