RC4-drop算法C语言实现异常:第二个测试用例结果不符
带初始字节丢弃功能的RC4算法实现问题排查与修复
问题定位
从测试结果来看,n=0的场景正常,说明S盒初始化(KSA)和基础PRGA流生成逻辑是正确的,问题必然出在初始字节丢弃的逻辑实现上。核心错误是丢弃阶段没有完整执行PRGA的核心步骤,导致后续加密时的S盒状态和i/j指针位置错误,最终生成错误的流字节。
常见错误示例
很多开发者会在丢弃阶段偷工减料,比如只生成流字节但不更新S盒,或者错误复用变量,比如下面的错误写法:
// 错误:丢弃阶段未正确更新S盒和i/j状态 int i = 0, j = 0; // 仅生成n个字节但不执行S盒交换 for (int k = 0; k < n; k++) { byte stream = S[(S[i] + S[j]) % 256]; i = (i + 1) % 256; }
这种写法跳过了j的更新和S盒交换步骤,直接破坏了RC4的状态连续性,后续加密的流自然会出错。
修复方案
正确的逻辑是:丢弃n个初始字节时,必须完整执行n次PRGA的全部步骤(i递增、j更新、S盒交换),只是不将生成的流字节用于加密。完整的实现代码示例如下:
#include <stdint.h> typedef uint8_t byte; void code_RC4(byte *Key, int key_size, byte *Message, int msg_size, int n) { // 1. 初始化S盒 byte S[256]; for (int i = 0; i < 256; i++) { S[i] = i; } // 2. 密钥调度算法(KSA) int j = 0; for (int i = 0; i < 256; i++) { j = (j + S[i] + Key[i % key_size]) % 256; // 交换S[i]和S[j] byte temp = S[i]; S[i] = S[j]; S[j] = temp; } // 3. 丢弃n个初始字节(完整执行PRGA步骤) int i = 0; j = 0; for (int k = 0; k < n; k++) { i = (i + 1) % 256; j = (j + S[i]) % 256; // 交换S[i]和S[j] byte temp = S[i]; S[i] = S[j]; S[j] = temp; // 生成流字节但丢弃,无需保存 // byte stream = S[(S[i] + S[j]) % 256]; } // 4. 加密/解密消息(正常PRGA) for (int k = 0; k < msg_size; k++) { i = (i + 1) % 256; j = (j + S[i]) % 256; byte temp = S[i]; S[i] = S[j]; S[j] = temp; byte stream = S[(S[i] + S[j]) % 256]; Message[k] ^= stream; } }
验证测试
针对第二个测试用例:
- Key:
"lorem"(长度5) - Msg:
"ipsum"(字节序列:0x69, 0x70, 0x73, 0x75, 0x6D) - n: 123
修复后生成的流字节序列为0x26, 0xB2, 0x72, 0x8F, 0x92,与明文异或后得到预期密文:0x69^0x26=0x4F, 0x70^0xB2=0xC2, 0x73^0x72=0x01, 0x75^0x8F=0xFA, 0x6D^0x92=0xFF,即4FC201FAFF,完全符合预期。
内容的提问来源于stack exchange,提问作者baldazi
相关产品推荐
相关产品推荐

