fish2018/pansou · error

解密密码失败

Error message

解密密码失败: %w

What it means

Wraps the failure of p.decryptPassword when trying to decrypt a user's stored EncryptedPassword during the login flow. The library keeps user passwords encrypted at rest and decrypts them just before calling doLogin; if decryption fails (wrong key, corrupted ciphertext, unsupported format), the login aborts and this wrapped error is returned so the underlying cause is preserved via %w.

Solutions

  1. Re-enter/re-save the account's plain password so EncryptedPassword is re-encrypted with the current key.
  2. Verify the encryption key/configuration is the same one used when the password was stored.
  3. Enable DebugLog to see the raw decrypt error printed by decryptPassword and fix the specific cause.
  4. Update the plugin if the EncryptedPassword was produced by an older/other version with a different scheme.

Example fix

// before
user.EncryptedPassword = oldBase64BlobFromOtherInstance
// after
user.EncryptedPassword = encryptWithCurrentKey(plainPassword) // re-save credentials
Defensive patterns

Strategy: try-catch

Validate before calling

if user == nil || user.EncryptedPassword == "" {
    return errors.New("user has no encrypted password stored")
}

Try / catch

password, err := p.decryptPassword(user.EncryptedPassword)
if err != nil {
    // errors.Is/As on the wrapped cause; recover by re-saving credentials
    return fmt.Errorf("re-save credentials for user %s: %w", user.Username, err)
}

Prevention

When it happens

Trigger: Calling the plugin's login/relogin path (e.g. reloginUser) for a user whose EncryptedPassword cannot be decrypted: ciphertext produced by a different encryption key or plugin version, empty/corrupted stored password, or an unsupported encryption scheme in decryptPassword.

Common situations: Users migrated from another instance with a different encryption key; encrypted password blob truncated in the config/store; plugin upgraded and the decryption scheme changed; EncryptedPassword field pasted manually instead of the encrypted value.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/b35654c05d1ca797. Report an issue: GitHub.

Appendix: source

Thrown at plugin/gying/gying.go:2276

	}
	return b
}

// ============ 重新登录逻辑 ============

// reloginUser 重新登录指定用户
func (p *GyingPlugin) reloginUser(user *User) error {
	if DebugLog {
		fmt.Printf("[Gying] 🔄 开始重新登录用户: %s\n", user.Username)
	}

	// 解密密码
	password, err := p.decryptPassword(user.EncryptedPassword)
	if err != nil {
		if DebugLog {
			fmt.Printf("[Gying] ❌ 解密密码失败: %v\n", err)
		}
		return fmt.Errorf("解密密码失败: %w", err)
	}

	// 执行登录
	scraper, cookie, err := p.doLogin(user.Username, password)
	if err != nil {
		if DebugLog {
			fmt.Printf("[Gying] ❌ 重新登录失败: %v\n", err)
		}
		return fmt.Errorf("重新登录失败: %w", err)
	}

	// 更新scraper实例
	p.scrapers.Store(user.Hash, scraper)

	// 更新用户信息
	user.Cookie = cookie
	user.LoginAt = time.Now()
	user.ExpireAt = time.Now().AddDate(0, 4, 0)

View on GitHub (pinned to beaa561337)