minitotp 0.1.0__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.
- minitotp-0.1.0/PKG-INFO +12 -0
- minitotp-0.1.0/minitotp/__init__.py +23 -0
- minitotp-0.1.0/minitotp/base32.py +27 -0
- minitotp-0.1.0/minitotp/wxtotp.py +61 -0
- minitotp-0.1.0/minitotp.egg-info/PKG-INFO +12 -0
- minitotp-0.1.0/minitotp.egg-info/SOURCES.txt +9 -0
- minitotp-0.1.0/minitotp.egg-info/dependency_links.txt +1 -0
- minitotp-0.1.0/minitotp.egg-info/requires.txt +3 -0
- minitotp-0.1.0/minitotp.egg-info/top_level.txt +1 -0
- minitotp-0.1.0/pyproject.toml +23 -0
- minitotp-0.1.0/setup.cfg +4 -0
minitotp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: minitotp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Standard TOTP (RFC6238) two-factor authentication SDK, pure standard library
|
|
5
|
+
License: MIT
|
|
6
|
+
Keywords: totp,2fa,otpauth,rfc6238,hotp,security
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Topic :: Security
|
|
10
|
+
Requires-Python: >=3.7
|
|
11
|
+
Provides-Extra: qr
|
|
12
|
+
Requires-Dist: qrcode[pil]; extra == "qr"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# minitotp —— 标准 TOTP(RFC6238)二次验证 SDK(纯标准库)
|
|
2
|
+
"""Standard TOTP (RFC6238) two-factor authentication SDK.
|
|
3
|
+
|
|
4
|
+
Pure standard-library implementation. Provides secret generation, otpauth
|
|
5
|
+
URI building, optional QR SVG, TOTP calculation and verification.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .wxtotp import (
|
|
9
|
+
generate_secret,
|
|
10
|
+
build_otpauth_uri,
|
|
11
|
+
generate_qr_svg,
|
|
12
|
+
calc_totp,
|
|
13
|
+
verify_code,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__version__ = "0.1.0"
|
|
17
|
+
__all__ = [
|
|
18
|
+
"generate_secret",
|
|
19
|
+
"build_otpauth_uri",
|
|
20
|
+
"generate_qr_svg",
|
|
21
|
+
"calc_totp",
|
|
22
|
+
"verify_code",
|
|
23
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# sdk/python/base32.py —— RFC4648 Base32(纯标准库实现)
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
|
5
|
+
_ALPHABET_REVERSE = {c: i for i, c in enumerate(_ALPHABET)}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def b32decode(s):
|
|
9
|
+
"""Base32 解码,忽略大小写与非 base32 字符,返回 bytes。"""
|
|
10
|
+
s = s.upper()
|
|
11
|
+
s = re.sub(r"[^A-Z2-7]", "", s)
|
|
12
|
+
bits = ""
|
|
13
|
+
for c in s:
|
|
14
|
+
bits += format(_ALPHABET_REVERSE[c], "05b")
|
|
15
|
+
out = bytearray()
|
|
16
|
+
for i in range(0, len(bits) - 7, 8):
|
|
17
|
+
out.append(int(bits[i:i + 8], 2))
|
|
18
|
+
return bytes(out)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def b32encode(buf):
|
|
22
|
+
"""Base32 编码(无填充),返回 str。"""
|
|
23
|
+
bits = "".join(format(b, "08b") for b in buf)
|
|
24
|
+
out = []
|
|
25
|
+
for i in range(0, len(bits) - 4, 5):
|
|
26
|
+
out.append(_ALPHABET[int(bits[i:i + 5], 2)])
|
|
27
|
+
return "".join(out)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# sdk/python/wxtotp.py —— TOTP 后端 SDK(RFC6238),仅用标准库
|
|
2
|
+
import os
|
|
3
|
+
import hmac
|
|
4
|
+
import hashlib
|
|
5
|
+
import time
|
|
6
|
+
from urllib.parse import quote
|
|
7
|
+
from .base32 import b32decode, b32encode
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def generate_secret(bits=160):
|
|
11
|
+
"""生成 base32 编码随机密钥(加密安全随机)。"""
|
|
12
|
+
raw = os.urandom((bits + 7) // 8)
|
|
13
|
+
return b32encode(raw)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def build_otpauth_uri(issuer, account, secret, period=30, digits=6):
|
|
17
|
+
"""构造 otpauth://totp URI。"""
|
|
18
|
+
return (
|
|
19
|
+
f"otpauth://totp/{quote(issuer)}:{quote(account)}"
|
|
20
|
+
f"?secret={secret}&issuer={quote(issuer)}&period={period}"
|
|
21
|
+
f"&digits={digits}&algorithm=SHA1"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def generate_qr_svg(uri):
|
|
26
|
+
"""生成二维码 SVG 文本(可选依赖 qrcode 库)。"""
|
|
27
|
+
try:
|
|
28
|
+
import qrcode
|
|
29
|
+
from io import BytesIO
|
|
30
|
+
except ImportError:
|
|
31
|
+
raise RuntimeError(
|
|
32
|
+
"可选依赖 qrcode 未安装。请先 pip install qrcode[pil],或用标准库版本跳过二维码。"
|
|
33
|
+
)
|
|
34
|
+
img = qrcode.make(uri)
|
|
35
|
+
buf = BytesIO()
|
|
36
|
+
img.save(buf, format="SVG")
|
|
37
|
+
return buf.getvalue().decode("utf-8")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def calc_totp(secret_b32, ts=None, period=30, digits=6):
|
|
41
|
+
"""计算 TOTP 验证码。"""
|
|
42
|
+
if ts is None:
|
|
43
|
+
ts = time.time()
|
|
44
|
+
key = b32decode(secret_b32)
|
|
45
|
+
t_int = int(ts // period)
|
|
46
|
+
t_bytes = t_int.to_bytes(8, byteorder="big")
|
|
47
|
+
h = hmac.new(key, t_bytes, hashlib.sha1).digest()
|
|
48
|
+
offset = h[19] & 0x0F
|
|
49
|
+
bin_code = int.from_bytes(h[offset:offset + 4], byteorder="big") & 0x7FFFFFFF
|
|
50
|
+
mod = 10 ** digits
|
|
51
|
+
return f"{bin_code % mod:0{digits}d}"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def verify_code(input_code, secret_b32, window=1, period=30, digits=6, ts=None):
|
|
55
|
+
"""校验验证码,支持时间窗口容错。"""
|
|
56
|
+
if ts is None:
|
|
57
|
+
ts = time.time()
|
|
58
|
+
for i in range(-window, window + 1):
|
|
59
|
+
if calc_totp(secret_b32, ts + i * period, period, digits) == input_code:
|
|
60
|
+
return True
|
|
61
|
+
return False
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: minitotp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Standard TOTP (RFC6238) two-factor authentication SDK, pure standard library
|
|
5
|
+
License: MIT
|
|
6
|
+
Keywords: totp,2fa,otpauth,rfc6238,hotp,security
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Topic :: Security
|
|
10
|
+
Requires-Python: >=3.7
|
|
11
|
+
Provides-Extra: qr
|
|
12
|
+
Requires-Dist: qrcode[pil]; extra == "qr"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
minitotp
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# sdk/python/pyproject.toml —— minitotp Python 打包配置
|
|
2
|
+
[build-system]
|
|
3
|
+
requires = ["setuptools>=61"]
|
|
4
|
+
build-backend = "setuptools.build_meta"
|
|
5
|
+
|
|
6
|
+
[project]
|
|
7
|
+
name = "minitotp"
|
|
8
|
+
version = "0.1.0"
|
|
9
|
+
description = "Standard TOTP (RFC6238) two-factor authentication SDK, pure standard library"
|
|
10
|
+
requires-python = ">=3.7"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
keywords = ["totp", "2fa", "otpauth", "rfc6238", "hotp", "security"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Topic :: Security",
|
|
17
|
+
]
|
|
18
|
+
# 可选依赖:generate_qr_svg 需要 qrcode 库
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
qr = ["qrcode[pil]"]
|
|
21
|
+
|
|
22
|
+
[tool.setuptools]
|
|
23
|
+
packages = ["minitotp"]
|
minitotp-0.1.0/setup.cfg
ADDED