{"record":{"id":"c49a57561b7f0cd9","repo":"Tencent/WeKnora","slug":"aes-key-too-short-d-bytes","errorCode":null,"errorMessage":"aes key too short: %d bytes","messagePattern":"aes key too short: (.+?) bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/im/wecom/ws_adapter.go","lineNumber":143,"sourceCode":"\treturn io.NopCloser(bytes.NewReader(decrypted)), fileName, nil\n}\n\n// decryptAESCBC decrypts data encrypted with AES-256-CBC using PKCS#7 padding.\n// The aesKeyB64 is the base64-encoded AES key provided per-message by WeCom.\n// IV is the first 16 bytes of the decoded AES key.\nfunc decryptAESCBC(ciphertext []byte, aesKeyB64 string) ([]byte, error) {\n\t// WeCom's per-message aeskey is base64-encoded (43 chars → 32 bytes after decode)\n\taesKey, err := base64.StdEncoding.DecodeString(aesKeyB64 + \"=\")\n\tif err != nil {\n\t\t// Try without padding\n\t\taesKey, err = base64.RawStdEncoding.DecodeString(aesKeyB64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"base64 decode aes key: %w\", err)\n\t\t}\n\t}\n\n\tif len(aesKey) < 16 {\n\t\treturn nil, fmt.Errorf(\"aes key too short: %d bytes\", len(aesKey))\n\t}\n\n\tblock, err := aes.NewCipher(aesKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"new aes cipher: %w\", err)\n\t}\n\n\tif len(ciphertext) < aes.BlockSize {\n\t\treturn nil, fmt.Errorf(\"ciphertext too short: %d bytes\", len(ciphertext))\n\t}\n\tif len(ciphertext)%aes.BlockSize != 0 {\n\t\treturn nil, fmt.Errorf(\"ciphertext not a multiple of block size: %d bytes\", len(ciphertext))\n\t}\n\n\t// IV = first 16 bytes of the AES key\n\tiv := aesKey[:aes.BlockSize]\n\tmode := cipher.NewCBCDecrypter(block, iv)\n\tplaintext := make([]byte, len(ciphertext))","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/im/wecom/ws_adapter.go#L125-L161","documentation":"decryptAESCBC rejects AES keys shorter than 16 bytes because Go's crypto/aes only supports 16-, 24-, or 32-byte keys. The WeCom aeskey is expected to be base64 of a 16-byte (AES-128) key; fewer bytes means the key was decoded wrong or truncated.","triggerScenarios":"Calling decryptAESCBC (via DownloadFile) with an aesKey that decodes to fewer than 16 bytes — e.g. malformed base64 handled by a path that didn't error, a truncated key string, or passing the base64 string raw instead of decoded bytes.","commonSituations":"Manually trimmed/padded key stored in config; passing the base64-encoded key literally as the key bytes; WeCom SDK or message format change altering the aeskey field; copy/paste dropping characters.","solutions":["Verify the message's aeskey is valid base64 decoding to exactly 16 bytes; re-read it from the original message.","Check that decryptAESCBC actually base64-decodes the key before the length check (the error prints the decoded length).","Never truncate or trim the key string when storing/parsing messages.","If the key is genuinely short, the message is corrupt — re-fetch the message from WeCom."],"exampleFix":"// before\nkey, _ := base64.StdEncoding.DecodeString(strings.TrimSpace(msg.AesKey))\n// after\nkey, err := base64.StdEncoding.DecodeString(msg.AesKey)\nif err != nil || len(key) != 16 {\n    return fmt.Errorf(\"invalid aes key: decoded %d bytes\", len(key))\n}","handlingStrategy":"validation","validationCode":"decoded, err := base64.StdEncoding.DecodeString(msg.AesKey)\nif err != nil || len(decoded) < 16 {\n    return fmt.Errorf(\"refusing to decrypt: aes key decodes to %d bytes\", len(decoded))\n}","typeGuard":"func isUsableAESKey(key []byte) bool {\n    return len(key) == 16 || len(key) == 24 || len(key) == 32\n}","tryCatchPattern":"rc, name, err := adapter.DownloadFile(ctx, msg)\nif err != nil && strings.Contains(err.Error(), \"aes key too short\") {\n    // corrupt/mis-parsed message: re-fetch or skip\n}","preventionTips":["Never trim, truncate, or hand-edit the aeskey string.","Confirm the key is base64-decoded before use; check decoded length is 16/24/32.","Re-fetch the message if the key looks malformed rather than guessing.","Guard parsing code so field shifts can't silently shorten the key."],"tags":["wecom","encryption","aes","invalid-key"],"backgroundTag":"invalid-aes-key","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}