Python Keyring在Windows凭据管理器中无法覆盖条目,反而创建新条目
解决Python keyring在Windows凭据管理器中无法覆盖密码的问题
问题原因
你遇到的问题是因为keyring的Windows默认后端(如WinVault)在存储凭据时,会自动将用户名和服务名拼接成新的目标名称(Target Name)。比如传入service="User@Service"和username="User"时,后端会生成User@User@Service作为新的目标名称,从而创建新条目而非覆盖原有条目。
解决方案
直接使用win32cred模块(属于pywin32库)操作Windows凭据管理器,绕过keyring的封装层,精确控制目标名称实现覆盖:
- 首先安装pywin32库:
pip install pywin32
- 使用以下代码读取并覆盖指定条目:
import win32cred # 凭据管理器中显示的服务名(Target Name) target_name = "User@Service" # 用户名 username = "User" # 新密码 new_password = "NewPassword" # 读取现有凭据 try: cred = win32cred.CredRead(target_name, win32cred.CRED_TYPE_GENERIC, 0) old_password = cred['CredentialBlob'].decode('utf-16le') print(f"读取到旧密码: {old_password}") except win32cred.error as e: print(f"读取凭据失败: {e}") # 准备新的凭据信息 new_cred = { 'Type': win32cred.CRED_TYPE_GENERIC, 'TargetName': target_name, 'UserName': username, 'CredentialBlob': new_password.encode('utf-16le'), # 持久化级别:本地机器(可根据需求改为CRED_PERSIST_SESSION或CRED_PERSIST_ENTERPRISE) 'Persist': win32cred.CRED_PERSIST_LOCAL_MACHINE } # 写入凭据(自动覆盖同名TargetName的条目) try: win32cred.CredWrite(new_cred, 0) print("密码已成功覆盖") except win32cred.error as e: print(f"写入凭据失败: {e}")
说明
win32cred.CredRead和CredWrite直接对接Windows凭据管理器API,完全按照你指定的TargetName操作,不会自动拼接字段,因此可以准确覆盖原有条目。- 如果必须使用keyring库,可以尝试指定后端为
keyring.backends.Windows.WinVaultKeyring,但仍可能存在自动拼接的问题,不如直接使用win32cred灵活。
内容的提问来源于stack exchange,提问作者Godzy
相关产品推荐
相关产品推荐

