You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PBKDF2-SHA512哈希验证Python程序值解包报错问题求助

解决密码哈希验证中的ValueError: too many values to unpack (expected 4)问题

问题背景

开发Python程序实现密码与指定哈希值的验证功能时,使用ChatGPT生成的代码测试对应口令testing的示例哈希时,抛出ValueError: too many values to unpack (expected 4)错误。

原代码

import hashlib

def verify_password(password, hash_value):
    algorithm, iterations, salt, hashed_password = hash_value.split(':')
    iterations = int(iterations)
    
    new_hash = hashlib.pbkdf2_hmac('sha512', password.encode('utf-8'), salt.encode('utf-8'), iterations).hex()
    
    if hashed_password == new_hash:
        return True
    else:
        return False

stored_hash = input("Give your hash : ")

user_password = input("Give your password : ")

print("Password hash is :", stored_hash)

# Verify
if verify_password(user_password, stored_hash):
    print("Valid Password.")
else:
    print("Wrong password.")

示例哈希(对应口令testing)

:pbkdf2:sha512:30000:64:OSn313BE8n6uRs2ddby4EQ==:vkWCj+mYOfSMiKPm7ca+u4zBWPqzb4MmAcGJhAkhG02wssTdGuEKuSPFpVXK9cgfN2mdxLata/zL3UZcqUfDMA==

报错信息

Give your hash : :pbkdf2:sha512:30000:64:OSn313BE8n6uRs2ddby4EQ==:vkWCj+mYOfSMiKPm7ca+u4zBWPqzb4MmAcGJhAkhG02wssTdGuEKuSPFpVXK9cgfN2mdxLata/zL3UZcqUfDMA==

Give your password : testing*
Password hash is : :pbkdf2:sha512:30000:64:OSn313BE8n6uRs2ddby4EQ==:vkWCj+mYOfSMiKPm7ca+u4zBWPqzb4MmAcGJhAkhG02wssTdGuEKuSPFpVXK9cgfN2mdxLata/zL3UZcqUfDMA==
Traceback (most recent call last):
  File "c:\Users\mathy\Downloads\temp.py", line 22, in <module>
    if verify_password(user_password, stored_hash):
  File "c:\Users\mathy\Downloads\temp.py", line 4, in verify_password
    algorithm, iterations, salt, hashed_password = hash_value.split(':')
ValueError: too many values to unpack (expected 4)

错误原因

原代码假设哈希值通过:分割后仅包含4个部分,但实际示例哈希是带前缀的PBKDF2格式,结构为:pbkdf2:<算法>:<迭代次数>:<盐长度>:<Base64编码的盐>:<Base64编码的哈希值>。使用split(':')处理后会得到7个元素(含开头的空字符串),远多于代码预期的4个,因此触发解包错误。

此外,原代码存在两个逻辑问题:

  1. 直接对盐字符串执行encode('utf-8'),但实际盐是Base64编码的字节序列,需先解码为原始字节。
  2. 存储的哈希值是Base64编码格式,而代码中生成的哈希是Hex格式,两者无法直接比较。

修复后的代码

import hashlib
import base64

def verify_password(password, hash_value):
    # 分割哈希值并过滤空元素(处理开头的冒号)
    parts = [part for part in hash_value.split(':') if part]
    # 解析PBKDF2格式的各组成部分
    _, algorithm, iterations_str, _, salt_b64, hashed_b64 = parts
    iterations = int(iterations_str)
    
    # 将Base64编码的盐和哈希值解码为原始字节
    salt = base64.b64decode(salt_b64)
    stored_hash = base64.b64decode(hashed_b64).hex()
    
    # 计算密码的哈希值
    new_hash = hashlib.pbkdf2_hmac(
        algorithm=algorithm,
        password=password.encode('utf-8'),
        salt=salt,
        iterations=iterations
    ).hex()
    
    return new_hash == stored_hash

stored_hash = input("Give your hash : ")
user_password = input("Give your password : ").strip('*')  # 处理输入时可能误加的多余字符

print("Password hash is :", stored_hash)

# 验证密码
if verify_password(user_password, stored_hash):
    print("Valid Password.")
else:
    print("Wrong password.")

测试验证

运行修复后的代码,输入示例哈希和正确口令testing(注意去掉输入时误加的*),程序会输出Valid Password.,验证通过。

内容的提问来源于stack exchange,提问作者FallenScriptKiddie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 21:20:31