{"record":{"id":"4cb7df2f39a0b391","repo":"fish2018/pansou","slug":"iv-d-d","errorCode":null,"errorMessage":"IV长度不正确: 期望%d，实际%d","messagePattern":"IV长度不正确: 期望(.+?)，实际(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"plugin/sdso/sdso.go","lineNumber":408,"sourceCode":"\tif len(ciphertext) == 0 {\n\t\treturn \"\", fmt.Errorf(\"密文长度为0\")\n\t}\n\n\t// 检查密文长度是否为16的倍数\n\tif len(ciphertext)%aes.BlockSize != 0 {\n\t\treturn \"\", fmt.Errorf(\"密文长度不是AES块大小的倍数\")\n\t}\n\n\t// 创建AES块加密器\n\tblock, err := aes.NewCipher([]byte(AESKey))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建AES加密器失败: %w\", err)\n\t}\n\n\t// 创建CBC模式解密器\n\tiv := []byte(AESIV)\n\tif len(iv) != aes.BlockSize {\n\t\treturn \"\", fmt.Errorf(\"IV长度不正确: 期望%d，实际%d\", aes.BlockSize, len(iv))\n\t}\n\n\tmode := cipher.NewCBCDecrypter(block, iv)\n\n\t// 解密\n\tplaintext := make([]byte, len(ciphertext))\n\tmode.CryptBlocks(plaintext, ciphertext)\n\n\t// 去除PKCS7填充\n\tunpaddedText, err := removePKCS7Padding(plaintext)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"去除填充失败: %w\", err)\n\t}\n\n\treturn string(unpaddedText), nil\n}\n\n// removePKCS7Padding 去除PKCS7填充","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/sdso/sdso.go#L390-L426","documentation":"DecryptURL uses the package-level AESIV as the CBC initialization vector and checks that it is exactly aes.BlockSize (16) bytes. CBC mode requires an IV equal to the block size, so any other length aborts with this error reporting the expected and actual sizes. This is a configuration problem with the IV constant, not with the ciphertext.","triggerScenarios":"AESIV is defined with a byte length other than 16 — e.g. an 8-byte string, an empty value, or an encoded (hex/base64) IV passed raw. The error fires on every call to DecryptURL when the constant is wrong.","commonSituations":"Developer shortened or renamed the IV constant; IV loaded from config/env that is missing or wrong length; IV pasted with extra characters like quotes or newline.","solutions":["Make AESIV exactly 16 bytes (e.g. a 16-character string or 16-byte slice).","If the IV is hex/base64-encoded, decode it before use and assert length 16.","Add an init-time or unit test assertion len([]byte(AESIV)) == aes.BlockSize so a bad IV is caught at startup instead of at first decrypt.","Verify against the SDSO site's actual IV; site format changes may require updating the constant."],"exampleFix":"// before\nconst AESIV = \"shortiv\"\n// after\nconst AESIV = \"0123456789abcdef\" // exactly 16 bytes","handlingStrategy":"validation","validationCode":"iv := []byte(AESIV)\nif len(iv) != 16 {\n    return fmt.Errorf(\"AESIV must be 16 bytes, got %d\", len(iv))\n}","typeGuard":"func hasValidIV(iv []byte) bool { return len(iv) == 16 }","tryCatchPattern":null,"preventionTips":["Check IV length in an init() or unit test.","Trim quotes/whitespace/newlines from configured IV strings.","Decode encoded IVs (hex/base64) before length checks.","Keep key and IV validation in one shared startup check."],"tags":["crypto","aes","iv","config","go"],"backgroundTag":"invalid-config-value","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"}