Kamixitong/test_password_decode.py
2025-11-22 20:32:49 +08:00

105 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""测试密码哈希解码"""
import base64
import hashlib
import hmac
# 从数据库中的实际密码哈希
password_hash = "$pbkdf2-sha256$29000$N2aBd1I5Eaz5bYY2CXbu2A$1lEXwDoX9S5slrv0cFHsQ8fAj55m43.1mPbX5f.Ra0U"
password = "admin123"
print(f"密码哈希: {password_hash}")
print(f"密码: {password}\n")
# 解析
parts = password_hash.split('$')
if len(parts) == 5:
iterations = int(parts[2])
salt_str = parts[3]
hash_str = parts[4]
print(f"迭代次数: {iterations}")
print(f"Salt 字符串: {salt_str} (长度: {len(salt_str)})")
print(f"Hash 字符串: {hash_str} (长度: {len(hash_str)})")
print()
# 尝试解码 salt
print("=== 解码 Salt ===")
salt_variants = [
(salt_str, "原始"),
]
salt_bytes = None
for variant, desc in salt_variants:
try:
# 添加填充
missing = len(variant) % 4
if missing:
variant += '=' * (4 - missing)
decoded = base64.b64decode(variant, validate=False)
print(f"OK {desc}: 成功,长度 {len(decoded)}")
salt_bytes = decoded
break
except Exception as e:
print(f"FAIL {desc}: 失败 - {e}")
print()
print("=== 解码 Hash ===")
# 尝试多种方式解码 hash
hash_variants = [
(hash_str, "原始"),
(hash_str.replace('.', ''), "移除点号"),
(hash_str.replace('.', '+'), "点号替换为+"),
(hash_str.replace('.', '/'), "点号替换为/"),
(hash_str.replace('.', '='), "点号替换为="),
(hash_str.replace('.', 'A'), "点号替换为A"),
(hash_str.replace('.', 'B'), "点号替换为B"),
]
stored_hash_bytes = None
for variant, desc in hash_variants:
try:
# 移除填充
variant_clean = variant.rstrip('=')
# 添加填充
missing = len(variant_clean) % 4
if missing:
variant_clean += '=' * (4 - missing)
decoded = base64.b64decode(variant_clean, validate=False)
if decoded and len(decoded) > 0:
print(f"OK {desc}: 成功,长度 {len(decoded)}")
stored_hash_bytes = decoded
break
except Exception as e:
print(f"FAIL {desc}: 失败 - {e}")
print()
if salt_bytes and stored_hash_bytes:
print("=== 计算 PBKDF2 ===")
password_bytes = password.encode('utf-8')
computed_hash = hashlib.pbkdf2_hmac('sha256', password_bytes, salt_bytes, iterations)
print(f"计算的哈希长度: {len(computed_hash)}")
print(f"存储的哈希长度: {len(stored_hash_bytes)}")
match = hmac.compare_digest(computed_hash, stored_hash_bytes)
print(f"\n匹配结果: {match}")
if not match:
print("\n=== 尝试不同的 hash 长度 ===")
# 尝试不同的长度
for i in range(max(0, len(stored_hash_bytes) - 5), len(stored_hash_bytes) + 5):
if i == len(stored_hash_bytes):
continue
test_hash = stored_hash_bytes[:i] if i < len(stored_hash_bytes) else stored_hash_bytes + b'\x00' * (i - len(stored_hash_bytes))
if len(test_hash) == len(computed_hash):
test_match = hmac.compare_digest(computed_hash, test_hash)
if test_match:
print(f"OK 长度 {i} 匹配成功!")
break
else:
print("无法解码 salt 或 hash")