chenhg5/cc-connect · error
wecom-ws: invalid aeskey base64 length
Error message
wecom-ws: invalid aeskey base64 length
What it means
decodeWeComAESKey in platform/wecom/websocket_media.go validates the base64-encoded AES key supplied with WeCom websocket media URLs. It only accepts base64 strings whose length mod 4 leaves remainder 0, 2, or 3, appending the missing '=' padding itself; any other length (remainder 1, or absurdly long) cannot be valid padded base64, so it aborts. This guards against garbage keys before attempting a stdlib base64 decode.
Source
Thrown at platform/wecom/websocket_media.go:243
}
if len(key) != 32 {
return nil, fmt.Errorf("wecom-ws: aeskey hex length %d, want 32 bytes", len(key))
}
return key, nil
}
// URL-safe alphabet → standard (RFC 4648 §5)
s = strings.ReplaceAll(s, "-", "+")
s = strings.ReplaceAll(s, "_", "/")
switch len(s) % 4 {
case 0:
case 2:
s += "=="
case 3:
s += "="
default:
return nil, fmt.Errorf("wecom-ws: invalid aeskey base64 length")
}
key, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return nil, fmt.Errorf("wecom-ws: decode aeskey: %w", err)
}
if len(key) < 32 {
return nil, fmt.Errorf("wecom-ws: aeskey decoded length %d, need >= 32", len(key))
}
return key, nil
}
func isHexString(s string) bool {
for i := 0; i < len(s); i++ {
c := s[i]
switch {
case c >= '0' && c <= '9', c >= 'a' && c <= 'f', c >= 'A' && c <= 'F':
default:View on GitHub (pinned to 4000b2338a)
Solutions
- Check len(strings.TrimSpace(aesKey)) % 4 != 1 before calling; re-copy the EncodingAESKey from the WeCom admin console in full.
- If the key is hex-encoded, convert or pass it through the hex branch the tests cover (isHexString) rather than as base64.
- Normalize the key: strip whitespace, convert URL-safe '-_' to '+/' and re-pad with '=' to a multiple of 4 before decrypting.
Example fix
// before
raw := cfg.AESKey // e.g. truncated "abcde" (len 5)
plain, err := wecomDecryptFile(ciphertext, raw)
// after
raw := strings.TrimSpace(cfg.AESKey)
if len(raw)%4 == 1 {
return nil, fmt.Errorf("bad aes key length %d", len(raw))
}
plain, err := wecomDecryptFile(ciphertext, raw) Defensive patterns
Strategy: validation
Validate before calling
func validAESKeyLen(s string) bool {
s = strings.TrimSpace(s)
return len(s) > 0 && len(s)%4 != 1
} Prevention
- Paste the EncodingAESKey from the WeCom console without manual edits; strip only outer whitespace.
- Assert key length/charset at config-load time, before any media download.
When it happens
Trigger: Calling wecomDecryptFile (via downloadWeComWSMedia) with an aesKeyB64 string whose length % 4 == 1, e.g. a truncated or corrupted base64 key, a hex string of odd length, or a key with stray characters removed/added.
Common situations: Copying the WeCom bot EncodingAESKey out of the admin console and clipping a character; a URL-safe, unpadded key passed through a transformation that stripped padding incorrectly; storing the key in config with whitespace/newline stripped unevenly; passing a hex-encoded key (64 hex chars is fine, 63 is not).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- wecom-ws: decode aeskey: %w
- wecom: invalid callback_aes_key: %w
- wecom-ws: bot_id and bot_secret are required for websocket m
- wecom-ws: aeskey decoded length %d, need >= 32
- wecom-ws: empty ciphertext
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/3f3e98cb47304b89.
Report an issue: GitHub.