100 lines
3.8 KiB
Python
100 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
"""测试 Werkzeug base64 编码方式"""
|
|
|
|
from werkzeug.security import generate_password_hash, check_password_hash
|
|
import base64
|
|
import hashlib
|
|
|
|
# 测试旧格式的密码哈希(数据库中的格式)
|
|
old_hash = "$pbkdf2-sha256$29000$N2aBd1I5Eaz5bYY2CXbu2A$1lEXwDoX9S5slrv0cFHsQ8fAj55m43.1mPbX5f.Ra0U"
|
|
password = "admin123"
|
|
|
|
print(f"旧格式哈希: {old_hash}")
|
|
print(f"密码: {password}")
|
|
|
|
# 尝试使用 Werkzeug 验证
|
|
try:
|
|
result = check_password_hash(old_hash, password)
|
|
print(f"Werkzeug 验证结果: {result}")
|
|
except Exception as e:
|
|
print(f"Werkzeug 验证失败: {e}")
|
|
|
|
# 手动解析旧格式
|
|
if old_hash.startswith('$pbkdf2-sha256$'):
|
|
parts = old_hash.split('$')
|
|
print(f"\n部分数量: {len(parts)}")
|
|
if len(parts) == 5:
|
|
iterations = int(parts[2])
|
|
salt_str = parts[3]
|
|
hash_str = parts[4]
|
|
|
|
print(f"\n迭代次数: {iterations}")
|
|
print(f"Salt 字符串: {salt_str}")
|
|
print(f"Salt 长度: {len(salt_str)}")
|
|
print(f"Hash 字符串: {hash_str}")
|
|
print(f"Hash 长度: {len(hash_str)}")
|
|
|
|
# 尝试 base64 解码
|
|
try:
|
|
# 添加填充
|
|
def add_padding(s):
|
|
missing = len(s) % 4
|
|
return s + '=' * (4 - missing) if missing else s
|
|
|
|
# 处理点号 - 可能是 URL-safe base64 的变体
|
|
# 点号在 base64 中不存在,可能是其他字符的编码
|
|
# 尝试将点号替换为可能的 base64 字符
|
|
def fix_base64(s):
|
|
# 尝试不同的替换方式
|
|
# 点号可能是 + 或 / 的编码错误
|
|
s1 = s.replace('.', '+')
|
|
s2 = s.replace('.', '/')
|
|
s3 = s.replace('.', '=')
|
|
return [s, s1, s2, s3]
|
|
|
|
salt_padded = add_padding(salt_str)
|
|
hash_variants = [add_padding(h) for h in fix_base64(hash_str)]
|
|
|
|
print(f"\nSalt 填充后: {salt_padded}")
|
|
print(f"Hash 变体数量: {len(hash_variants)}")
|
|
|
|
salt_bytes = base64.b64decode(salt_padded, validate=False)
|
|
|
|
# 尝试所有变体
|
|
for i, hash_padded in enumerate(hash_variants):
|
|
try:
|
|
print(f"\n尝试 Hash 变体 {i}: {hash_padded[:50]}...")
|
|
hash_bytes = base64.b64decode(hash_padded, validate=False)
|
|
print(f"变体 {i} 解码成功,长度: {len(hash_bytes)}")
|
|
|
|
# 计算 PBKDF2
|
|
password_bytes = password.encode('utf-8')
|
|
computed = hashlib.pbkdf2_hmac('sha256', password_bytes, salt_bytes, iterations)
|
|
|
|
import hmac
|
|
match = hmac.compare_digest(computed, hash_bytes)
|
|
print(f"变体 {i} 哈希匹配: {match}")
|
|
if match:
|
|
break
|
|
except Exception as e:
|
|
print(f"变体 {i} 失败: {e}")
|
|
|
|
print(f"\nSalt 解码成功,长度: {len(salt_bytes)}")
|
|
print(f"Hash 解码成功,长度: {len(hash_bytes)}")
|
|
|
|
# 计算 PBKDF2
|
|
password_bytes = password.encode('utf-8')
|
|
computed = hashlib.pbkdf2_hmac('sha256', password_bytes, salt_bytes, iterations)
|
|
|
|
print(f"\n计算的哈希长度: {len(computed)}")
|
|
print(f"存储的哈希长度: {len(hash_bytes)}")
|
|
|
|
import hmac
|
|
match = hmac.compare_digest(computed, hash_bytes)
|
|
print(f"\n哈希匹配: {match}")
|
|
except Exception as e:
|
|
print(f"\n解码/验证失败: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|