C语言XOR+Base64加解密程序异常:密钥部分变更仍可解密求助
核心问题原因
你遇到的密钥修改后仍能解密的问题,本质是两个低级错误共同导致的:
- 加密时只用到了密钥的前N位,N等于明文长度,只要你修改的是密钥中超过明文长度的部分,根本不会参与加解密运算,自然不影响解密结果
- 你使用
strlen()计算加密后二进制数据的长度,XOR运算会产生值为\0的字节,strlen()遇到\0就会终止计数,导致很多时候后面的密文根本没有被编码进Base64结果,对应的密钥位自然也不会生效
代码存在的其他问题
- 密钥没有循环使用:标准的变长XOR加密应该用
key[i % keylen]取密钥字符,你的写法在明文长度超过密钥长度时会直接访问密钥数组外的栈内存,属于未定义行为 - 固定长度栈缓冲区风险:
cipher_2固定分配65536字节,输入明文超过这个长度会直接栈溢出 - 循环中重复调用
strlen():每次循环都重新计算字符串长度,性能会大幅下降 - 解密函数不符合声明要求:定义返回值为
char *但没有返回任何内容 - 加密后的缓冲区没有边界处理:未初始化的栈数组内容会被误算进密文长度
修复方案
修复后的加密函数
// 加密过程 char * encrypt(char strinp[], char key[]){ int keylen = strlen(key); int plain_len = strlen(strinp); // 动态申请缓冲区,避免固定长度栈溢出 char *cipher_2 = malloc(plain_len); if (!cipher_2) return NULL; for(int i = 0; i < plain_len; i++){ char cipher_1 = strinp[i] + keylen; // 循环取密钥字符,避免越界 cipher_2[i] = cipher_1 ^ key[i % keylen]; } size_t input_size = plain_len; char * encoded_data = base64_encode(cipher_2, input_size, &input_size); free(cipher_2); return encoded_data; }
修复后的解密函数
// 解密过程 char * decrypt(char strinp[], char key[]){ int keylen = strlen(key); size_t decode_size = strlen(strinp); char * decoded_data = base64_decode(strinp, decode_size, &decode_size); if (!decoded_data) return NULL; // 动态申请明文缓冲区,多留一位存终止符 char *plain = malloc(decode_size + 1); if (!plain) { free(decoded_data); return NULL; } for(int i = 0; i < decode_size; i++){ char cipher_2 = decoded_data[i] ^ key[i % keylen]; plain[i] = cipher_2 - keylen; } // 加字符串终止符,方便后续使用 plain[decode_size] = '\0'; free(decoded_data); // 输出明文 printf("%s", plain); return plain; }
额外优化建议
- 不要在加密逻辑里硬编码加固定偏移
keylen,这个操作不会提升安全性,反而增加运算开销 - 输入输出的字符串内存要明确管理,避免内存泄漏
- XOR属于流加密,本身安全性较低,仅适合学习使用,不要用于生产环境的敏感数据加密
内容的提问来源于stack exchange,提问作者NotAidan
相关产品推荐
相关产品推荐

