手把手复现IDEA加密:用Python从零理解128位密钥的轮运算 手把手复现IDEA加密用Python从零理解128位密钥的轮运算在密码学领域IDEAInternational Data Encryption Algorithm算法以其简洁而强大的设计闻名。不同于DES等更广为人知的算法IDEA采用128位密钥和8轮运算结构在安全性和效率之间取得了优雅的平衡。本文将用Python代码一步步拆解IDEA的核心机制特别聚焦于其独特的子密钥生成和轮运算过程。通过实际编码您将直观理解128位主密钥如何通过循环移位生成52个子密钥模加mod 2¹⁶和模乘mod 2¹⁶1运算的数学原理与实现8轮运算中数据块如何被混淆和扩散加密/解密的可逆性验证方法1. 环境准备与基础运算实现1.1 初始化设置我们先定义必要的常量和基础函数。IDEA操作16位无符号整数Python中可用ctypes.c_uint16确保数值范围正确from ctypes import c_uint16 MOD_ADD 2**16 # 模加基数 MOD_MUL 2**16 1 # 模乘基数 KEY_ROTATE 25 # 子密钥生成时的循环左移位数1.2 核心数学运算IDEA依赖三种特殊运算——按位异或、模加和模乘。后两者需要特别处理def idea_add(a, b): 模2^16加法 return c_uint16(a b).value def idea_mul(a, b): 模(2^16 1)乘法0视为2^16 a 2**16 if a 0 else a b 2**16 if b 0 else b return c_uint16((a * b) % MOD_MUL).value注意模乘运算中0需要特殊处理为2¹⁶这是IDEA算法的独特设计。2. 子密钥生成机制2.1 128位主密钥拆分IDEA的密钥扩展将128位主密钥转换为52个16位子密钥。首先生成初始密钥块def generate_initial_subkeys(master_key): 将128位主密钥拆分为8个16位块 return [(master_key (112 - 16*i)) 0xFFFF for i in range(8)]2.2 循环移位与密钥扩展每轮需要6个子密钥8轮共需48个加上输出变换的4个总计52个。密钥不足时需循环左移25位def rotate_key(key, bitsKEY_ROTATE): 128位循环左移 return ((key bits) | (key (128 - bits))) 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF def expand_key(master_key): subkeys [] current_key master_key for _ in range(7): # 前7轮各生成6个子密钥 subkeys.extend(generate_initial_subkeys(current_key)[:6]) current_key rotate_key(current_key) # 第8轮及输出变换 subkeys.extend(generate_initial_subkeys(current_key)[:4]) return subkeys密钥生成过程可视化如下轮次使用的密钥位范围操作说明11-96位直接取前6个子密钥297-128位 移位后1-64位先使用剩余位再循环移位补足365-128位 移位后1-32位同上433-128位刚好满足6个子密钥需求5-8重复1-4轮模式每次移位25位3. 轮运算实现3.1 单轮运算结构每轮对4个16位数据块执行以下操作def idea_round(x1, x2, x3, x4, subkeys): 单轮IDEA运算 # 步骤1模乘和模加 s1 idea_mul(x1, subkeys[0]) s2 idea_add(x2, subkeys[1]) s3 idea_add(x3, subkeys[2]) s4 idea_mul(x4, subkeys[3]) # 步骤2中间变量计算 t0 idea_mul(s1 ^ s3, subkeys[4]) t1 idea_add(s2 ^ s4, t0) t2 idea_mul(t1, subkeys[5]) t3 idea_add(t0, t2) # 步骤3输出组合 y1 s1 ^ t2 y2 s3 ^ t2 y3 s2 ^ t3 y4 s4 ^ t3 return y1, y2, y3, y43.2 完整8轮加密流程def idea_encrypt(block, subkeys): x1, x2, x3, x4 block # 8轮主运算 for i in range(8): round_keys subkeys[i*6 : (i1)*6] x1, x2, x3, x4 idea_round(x1, x2, x3, x4, round_keys) x2, x3 x3, x2 # 交换中间两个块 # 输出变换 y1 idea_mul(x1, subkeys[48]) y2 idea_add(x3, subkeys[49]) # 注意x2和x3位置交换 y3 idea_add(x2, subkeys[50]) y4 idea_mul(x4, subkeys[51]) return (y1, y2, y3, y4)4. 解密实现与验证4.1 解密子密钥计算解密需要生成逆子密钥def multiplicative_inverse(x): 计算模(2^16 1)乘法逆元 for i in range(1, MOD_MUL): if idea_mul(x, i) 1: return i return 0 def prepare_decryption_keys(enc_keys): dec_keys [] # 前48个密钥的特殊处理 for i in reversed(range(8)): round_keys enc_keys[i*6 : (i1)*6] dec_keys.extend([ multiplicative_inverse(round_keys[0]), c_uint16(-round_keys[1]).value, c_uint16(-round_keys[2]).value, multiplicative_inverse(round_keys[3]), round_keys[4], round_keys[5] ]) # 最后4个密钥 dec_keys.extend([ multiplicative_inverse(enc_keys[48]), c_uint16(-enc_keys[49]).value, c_uint16(-enc_keys[50]).value, multiplicative_inverse(enc_keys[51]) ]) return dec_keys4.2 完整加解密验证def test_idea(): # 示例密钥和明文 master_key 0x2BD6459F82C5B300952C49104881FF48 plaintext (0x1234, 0x5678, 0x9ABC, 0xDEF0) # 密钥扩展 enc_keys expand_key(master_key) dec_keys prepare_decryption_keys(enc_keys) # 加密 ciphertext idea_encrypt(plaintext, enc_keys) print(fCiphertext: {[hex(x) for x in ciphertext]}) # 解密 decrypted idea_encrypt(ciphertext, dec_keys) print(fDecrypted: {[hex(x) for x in decrypted]}) assert decrypted plaintext, 解密失败运行结果应显示解密后的文本与原始明文一致验证算法正确性。通过这个完整实现您已经掌握了IDEA算法的核心机制。建议尝试修改轮次数或密钥长度观察对安全性的影响。