Download src/security.py from sidaier/fc: direct link, hf CLI and curl.
- Browser
- Download file 1.18 kB
-
https://huggingface.co/spaces/sidaier/fc/resolve/main/src/security.py
- Command line
-
hf download hf://spaces/sidaier/fc/src/security.py
-
curl -L -o security.py https://huggingface.co/spaces/sidaier/fc/resolve/main/src/security.py
1.18 kB
| """密码哈希:使用标准库 pbkdf2_hmac,零额外依赖。 | |
| 存储格式:pbkdf2_sha256$<iterations>$<salt_b64>$<hash_b64> | |
| """ | |
| from __future__ import annotations | |
| import base64 | |
| import hashlib | |
| import hmac | |
| import os | |
| ALGO = "pbkdf2_sha256" | |
| ITERATIONS = 200_000 | |
| def hash_password(password: str, *, iterations: int = ITERATIONS) -> str: | |
| """生成带盐的 pbkdf2 密码哈希。""" | |
| salt = os.urandom(16) | |
| dk = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, iterations) | |
| return f"{ALGO}${iterations}${_b64(salt)}${_b64(dk)}" | |
| def verify_password(password: str, stored: str) -> bool: | |
| """校验明文密码与存储哈希是否匹配(恒定时间比较)。""" | |
| try: | |
| algo, iters, salt_b64, hash_b64 = stored.split("$") | |
| if algo != ALGO: | |
| return False | |
| salt = base64.b64decode(salt_b64) | |
| expected = base64.b64decode(hash_b64) | |
| dk = hashlib.pbkdf2_hmac("sha256", password.encode("utf-8"), salt, int(iters)) | |
| return hmac.compare_digest(dk, expected) | |
| except (ValueError, TypeError): | |
| return False | |
| def _b64(raw: bytes) -> str: | |
| return base64.b64encode(raw).decode("ascii") | |