天下漏洞,尽知其名
MEDIUM

CVE-2026-71884 Bouncy Castle Java CTR 计数器回绕漏洞

影响攻击者无需密钥即可从密文恢复部分明文

MEDIUM
暂无 CVSS 评分
AI 研判

Bouncy Castle for Java LTS 2.73.13 之前的原生一次性 CTR 分组密码实现未校验输入长度是否超出 IV 剩余计数器空间。当 IV 为 13 至 15 字节时,计数器仅剩 1 至 3 字节,处理超长输入会导致计数器回绕、密钥流重复。

影响范围

Bouncy Castle for Java

Bouncy Castle for Java LTS 2.73.13 之前的版本,具体受影响版本范围以官方公告为准。

漏洞详情

CTR 模式中 IV 与块计数器共用 16 字节块,IV 过长会压缩计数器可寻址的块数。原生一次性路径缺少计数器范围校验,超长输入使计数器回绕、同一密钥流被重复使用,导致两段明文可用同一密钥流加密,从而可仅凭密文恢复明文,且调用方不会收到异常或短长度提示。

利用条件与风险

利用前提是应用使用 13 至 15 字节 IV 的原生一次性 CTR 接口并传入超出计数器空间的输入;流式实现和可移植 AESCTRPacketCipher 会拒绝此类请求,因此实际风险取决于具体调用路径。

修复建议

升级到 Bouncy Castle for Java LTS 2.73.13 或更高版本,该版本会在写入输出前预检 IV 派生计数器范围并拒绝超长请求;临时缓解可改用流式实现或可移植 AESCTRPacketCipher,并避免使用过长 IV。

原始情报

In Bouncy Castle for Java LTS before 2.73.13, the native one-shot CTR packet cipher did not check that the requested input length fitted the counter space the IV left. In CTR mode the IV and the block counter share one 16-byte block, so an IV of 13 to 15 bytes leaves a counter of only 1 to 3 bytes, addressing 256, 65536 or 16777216 blocks respectively. Given a longer input the counter wrapped and the keystream repeated from the start of the same packet, and the call then returned the full input length as though every byte had been correctly transformed. Two segments of the message were therefore encrypted under the same keystream, so their plaintexts can be recovered from the ciphertext alone, without the key, while the caller saw neither an exception nor a short length to indicate it. The streaming implementation validates at init and again while processing, and the portable AESCTRPacketCipher rejects such a request with “Counter in CTR/SIC mode out of range.”, but the native one-shot path has a single entry point and performed no counter-range validation there. It now preflights the IV-derived counter range and rejects an over-long request before any output is written, so the operation is failure-atomic and never reports success for bytes it did not correctly transform. A counter of four bytes or more cannot be exhausted by a Java int length and is unaffected, as is a full 16-byte IV, where the counter range is the caller’s responsibility. Bouncy Castle for Java (bcprov) is not affected, as it ships no native implementations.