{"record":{"id":"7eda1924c87e0a5f","repo":"grafana/k6","slug":"invalid-pkcs7-data","errorCode":null,"errorMessage":"invalid PKCS7 data","messagePattern":"invalid PKCS7 data","errorType":"validation","errorClass":"ErrInvalidPkcs7Data","httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/webcrypto/aes.go","lineNumber":661,"sourceCode":"\n// maxAESGcmAdditionalDataLength holds the value 2 ^ 64 - 1 as specified in\n// the [Web Crypto API spec] for the AES-GCM algorithm encryption operation.\n//\n// [Web Crypto API spec]: https://www.w3.org/TR/WebCryptoAPI/#aes-gcm-encryption-operation\nconst maxAESGcmAdditionalDataLength uint64 = (1 << 64) - 1\n\n// maxAESGcmIvLength holds the value 2 ^ 64 - 1 as specified in\n// the [Web Crypto API spec] for the AES-GCM algorithm encryption operation.\n//\n// [Web Crypto API spec]: https://www.w3.org/TR/WebCryptoAPI/#aes-gcm-encryption-operation\nconst maxAESGcmIvLength uint64 = (1 << 64) - 1\n\nvar (\n\t// ErrInvalidBlockSize is returned when the given block size is invalid.\n\tErrInvalidBlockSize = errors.New(\"invalid block size\")\n\n\t// ErrInvalidPkcs7Data is returned when the given data is invalid.\n\tErrInvalidPkcs7Data = errors.New(\"invalid PKCS7 data\")\n)\n\n// pKCS7Padding adds PKCS7 padding to the given plaintext.\n// It implements section 10.3 of [RFC 2315].\n//\n// [RFC 2315]: https://www.rfc-editor.org/rfc/rfc2315#section-10.3\nfunc pKCS7Pad(plaintext []byte, blockSize int) ([]byte, error) {\n\tif blockSize <= 0 {\n\t\treturn nil, ErrInvalidBlockSize\n\t}\n\n\tif len(plaintext) == 0 {\n\t\treturn nil, ErrInvalidPkcs7Data\n\t}\n\n\tl := len(plaintext)\n\tpadding := blockSize - (l % blockSize)\n\tpaddingText := bytes.Repeat([]byte{byte(padding)}, padding) //nolint:gosec","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/webcrypto/aes.go#L643-L679","documentation":"ErrInvalidPkcs7Data is returned by pKCS7Pad (internal/js/modules/k6/webcrypto/aes.go:673) when the plaintext is empty: `if len(plaintext) == 0`. The AES-CBC implementation in k6 calls pKCS7Pad unconditionally (aes.go:286), so encrypting a zero-length buffer with AES-CBC fails instead of producing the all-padding ciphertext that other WebCrypto implementations return. It is a k6-specific limitation of the AES-CBC encrypt operation.","triggerScenarios":"`await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, new Uint8Array(0))` or passing an empty ArrayBuffer/TypedArray as data with AES-CBC. Other modes (e.g. AES-GCM) accept empty data fine.","commonSituations":"Encrypting request payloads that are legitimately empty (empty POST bodies, empty JSON); edge-case handling in crypto round-trip tests; code ported from Node.js or browsers where empty plaintext is accepted.","solutions":["Guard the empty case before encrypting: return early, or encrypt a sentinel byte","Switch the algorithm to AES-GCM, which handles zero-length plaintext in k6","If ciphertext compatibility matters, handle empty plaintext as a special case in your protocol"],"exampleFix":"// before\nconst ct = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, new Uint8Array(0));\n\n// after\nconst data = new Uint8Array(0);\nconst ct = data.length === 0\n  ? new ArrayBuffer(0) // protocol-level sentinel for empty payload\n  : await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data);","handlingStrategy":"validation","validationCode":"const data = new Uint8Array(raw);\nif (data.byteLength === 0) throw new Error('AES-CBC in k6 cannot encrypt empty plaintext; use AES-GCM or a sentinel');","typeGuard":null,"tryCatchPattern":"try {\n  ct = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, data);\n} catch (e) {\n  if (String(e.message).includes('invalid PKCS7 data') && data.byteLength === 0) {\n    ct = new ArrayBuffer(0); // app-level convention for empty payloads\n  } else { throw e; }\n}","preventionTips":["Never pass zero-length data to AES-CBC encrypt in k6","Prefer AES-GCM for new code — it accepts empty payloads and is authenticated","Add an explicit byteLength check at crypto helpers' entry points"],"tags":["webcrypto","aes-cbc","encryption","edge-case"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}