Base64编码原理详解:从字符表到编解码实现与工程实践
2026/10/14 9:36:57
SM4是中国国家密码管理局发布的对称加密标准(原名 SMS4),主要用于无线局域网标准(WAPI)及各类政务、金融应用。它在结构上属于分组密码算法。
SM4 的核心逻辑在于其非线性变换部分。
OFB (Output Feedback, 输出反馈模式)是对称加密的一种工作模式。它的最大特点是将 SM4 这种“块加密”引擎当作“伪随机数生成器”来使用。
在 OFB 模式下,SM4 不直接加密明文,而是加密上一次加密输出的反馈向量:
若以 Ek 表示使用密钥 k 的 SM4 加密函数,Pi 为明文块,Ci 为密文块,Oi 为输出块:
尽管 SM4-OFB 非常高效,但在实际工程中必须遵守以下准则:
这是 OFB 模式的致命伤。如果使用相同的密钥和相同的 IV 加密两段不同的明文,则:
攻击者可以通过异或结果推导出明文内容。IV 必须是不可预测且唯一的。
OFB 模式本身不提供完整性保护。攻击者虽然不知道明文,但可以通过翻转密文中的特定位(Bit-flipping attack)来精确修改解密后的明文。在安全要求高的场景,建议配合HMAC使用。
#include <iostream> #include <vector> #include <cstring> #include <gmssl/sm4.h> /** * SM4-OFB 加解密实现函数 * @param key 16字节密钥 * @param iv 16字节初始化向量 (每个消息必须唯一) * @param input 输入数据指针 * @param input_len 输入数据长度 * @param output 输出缓冲区指针 (长度应等于 input_len) */ void sm4_ofb_transform(const uint8_t key[16], const uint8_t iv[16], const uint8_t* input, size_t input_len, uint8_t* output) { SM4_KEY sm4_key; uint8_t iv_buffer[16]; uint8_t block_out[16]; int offset = 0; // 1. 初始化 SM4 密钥 sm4_set_encrypt_key(&sm4_key, key); // 2. 拷贝 IV,因为 OFB 需要不断更新反馈向量 memcpy(iv_buffer, iv, 16); // 3. 逐块处理 for (size_t i = 0; i < input_len; i++) { // 当处理到块的边界(或起始)时,生成新的密钥流块 if (offset == 0) { sm4_encrypt(&sm4_key, iv_buffer, block_out); // 将加密后的输出作为下一次加密的输入 (Feedback) memcpy(iv_buffer, block_out, 16); } // 4. 将密钥流与明文/密文异或 output[i] = input[i] ^ block_out[offset]; // 更新块内偏移,SM4 块大小为 16 字节 offset = (offset + 1) % 16; } } // 使用示例 int main() { uint8_t key[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; uint8_t iv[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; const char* text = "Hello, SM4-OFB Security!"; size_t len = strlen(text); std::vector<uint8_t> encrypted(len); std::vector<uint8_t> decrypted(len); // 加密 sm4_ofb_transform(key, iv, (uint8_t*)text, len, encrypted.data()); // 解密 (OFB 模式解密函数与加密完全一致,IV 需相同) sm4_ofb_transform(key, iv, encrypted.data(), len, decrypted.data()); std::cout << "Original: " << text << std::endl; std::cout << "Decrypted: " << std::string(decrypted.begin(), decrypted.end()) << std::endl; return 0; }| 特性 | SM4-ECB (基本模式) | SM4-CBC (链式模式) | SM4-OFB (反馈模式) |
|---|---|---|---|
| 安全性 | 低(易受模式分析) | 高 | 高(IV 唯一时) |
| 填充 | 需要 | 需要 | 不需要 |
| 并行计算 | 支持 | 不支持解密外 | 支持预计算 |
| 错误影响 | 仅本块 | 蔓延至下一块 | 无蔓延 |