{"record":{"id":"6cfe458e45d2c003","repo":"fish2018/pansou","slug":"ciphertext-too-short-6cfe45","errorCode":null,"errorMessage":"ciphertext too short","messagePattern":"ciphertext too short","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qqpd/qqpd.go","lineNumber":2350,"sourceCode":"\n\tciphertext, err := base64.StdEncoding.DecodeString(encrypted)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tblock, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tgcm, err := cipher.NewGCM(block)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tnonceSize := gcm.NonceSize()\n\tif len(ciphertext) < nonceSize {\n\t\treturn \"\", fmt.Errorf(\"ciphertext too short\")\n\t}\n\n\tnonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]\n\tplaintext, err := gcm.Open(nil, nonce, ciphertext, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(plaintext), nil\n}\n\n// ============ 定期清理 ============\n\n// startCleanupTask 定期清理任务\nfunc (p *QQPDPlugin) startCleanupTask() {\n\tticker := time.NewTicker(24 * time.Hour)\n\tfor range ticker.C {\n\t\tdeleted := p.cleanupExpiredUsers()","sourceCodeStart":2332,"sourceCodeEnd":2368,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qqpd/qqpd.go#L2332-L2368","documentation":"The AES-GCM decryption helper (decrypt, near plugin/qqpd/qqpd.go:2350) validates that the supplied ciphertext is at least as long as the GCM nonce size (12 bytes) before attempting gcm.Open. A shorter input can never be valid GCM output, so it fails fast with \"ciphertext too short\" instead of a confusing crypto error.","triggerScenarios":"Passing an empty string/byte slice, a plaintext value, or a truncated base64 payload to the decrypt function — anything shorter than gcm.NonceSize() (12) bytes after decoding.","commonSituations":"Config/cookie field stored unencrypted or re-encoded (e.g. double base64 decode stripping bytes); credential file truncated or partially written; wrong field passed to decrypt.","solutions":["Verify the input being decrypted is the exact encrypted output (base64 of nonce+ciphertext), not plaintext or a URL-decoded fragment.","Check for accidental encoding round-trips (e.g. base64 decoded twice) that shorten the payload.","Re-generate/re-store the encrypted credential with the same encrypt helper.","Confirm you are decrypting the right field — a wrong config key often yields an empty or short value."],"exampleFix":"// before\ndata, _ := base64.StdEncoding.DecodeString(input) // error ignored\ncleartext, err := decrypt(key, data)\n// after\ndata, err := base64.StdEncoding.DecodeString(input)\nif err != nil {\n    return \"\", fmt.Errorf(\"bad ciphertext encoding: %w\", err)\n}\ncleartext, err := decrypt(key, data)\nif err != nil && strings.Contains(err.Error(), \"ciphertext too short\") {\n    return \"\", fmt.Errorf(\"credential looks unencrypted or truncated; re-save it\")\n}","handlingStrategy":"validation","validationCode":"decoded, err := base64.StdEncoding.DecodeString(ciphertextB64)\nif err != nil || len(decoded) < 12 {\n    return fmt.Errorf(\"credential is not valid encrypted data (len=%d)\", len(decoded))\n}","typeGuard":"func looksEncrypted(s string) bool {\n    b, err := base64.StdEncoding.DecodeString(s)\n    return err == nil && len(b) >= 12\n}","tryCatchPattern":"plain, err := decrypt(key, data)\nif err != nil {\n    if strings.Contains(err.Error(), \"ciphertext too short\") {\n        // value was stored unencrypted or truncated — prompt re-save\n    } else {\n        // wrong key or corrupted data\n    }\n}","preventionTips":["Always base64-encode ciphertext at write time and decode at read time","Store a version/format marker alongside encrypted fields","Never skip the error from base64 decoding before decrypting","Verify key material is identical between encrypt and decrypt sides"],"tags":["crypto","aes-gcm","decryption","input-validation"],"backgroundTag":"ciphertext-too-short","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}