RC4逆向 详细了解RC4加密算法-CSDN博客
算法 在 密码学 中, RC4 (来自 Rivest Cipher 4 的缩写)是一种 流加密 算法, 密钥 长度可变。它加解密使用相同的密钥,因此也属于 对称加密算法 。RC4 是 有线等效加密 (WEP)中采用的加密算法,也曾经是 TLS 可采用的算法之一。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void rc4_init (unsigned char *s, unsigned char *key, unsigned long Len) { int i =0 , j = 0 ; unsigned char k[256 ] = {0 }; unsigned char tmp = 0 ; for (i=0 ;i<256 ;i++) { s[i] = i; k[i] = key[i%Len]; } for (i=0 ; i<256 ; i++) { j=(j+s[i]+k[i])%256 ; tmp = s[i]; s[i] = s[j]; s[j] = tmp; } }void rc4_crypt (unsigned char *s, unsigned char *Data, unsigned long Len) { int i = 0 , j = 0 , t = 0 ; unsigned long k = 0 ; unsigned char tmp; for (k=0 ;k<Len;k++) { i=(i+1 )%256 ; j=(j+s[i])%256 ; tmp = s[i]; s[i] = s[j]; s[j] = tmp; t=(s[i]+s[j])%256 ; Data[k] ^= s[t]; } }
其伪代码表示为:
初始化长度为 256 的 S 盒 。第一个 for 循环将 0 到 255 的互不重复的元素装入 S 盒。第二个 for 循环根据密钥打乱 S 盒。
1 2 3 4 5 6 7 8 for i from 0 to 255 S[i] := i endfor j := 0 for ( i=0 ; i<256 ; i++) j := (j + S[i] + key[i mod keylength]) % 256 swap values of S[i] and S[j] endfor
下面 i,j 是两个指针。每收到一个字节,就进行 while 循环。通过一定的算法((a),(b))定位 S 盒中的一个元素,并与输入字节异或,得到 k。循环中还改变了 S 盒( © )。如果输入的是 明文 ,输出的就是 密文 ;如果输入的是密文,输出的就是明文。
1 2 3 4 5 6 7 8 9 i := 0 j := 0 while GeneratingOutput: i := (i + 1 ) mod 256 j := (j + S[i]) mod 256 swap values of S[i] and S[j] k := inputByte ^ S[(S[i] + S[j]) % 256 ] output K endwhile
此算法保证每 256 次循环中 S 盒的每个元素至少被交换过一次
pyexp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 def rc4_init(key): s = list(range(256)) # 初始化 s 为 0 到 255 的列表 j = 0 k = bytearray(256) # 必须为无符号字节数组 key_len = len(key) # 填充 k 并执行密钥调度算法(KSA) for i in range(256): k[i] = key[i % key_len] for i in range(256): j = (j + s[i] + k[i]) % 256 s[i], s[j] = s[j], s[i] # 交换 s[i] 和 s[j] return s # 返回初始化后的状态数组 s def rc4_crypt(s, data): i = 0 j = 0 result = bytearray(len(data)) # 用于存储加密/解密结果 # 加解密过程 for k in range(len(data)): i = (i + 1) % 256 j = (j + s[i]) % 256 s[i], s[j] = s[j], s[i] # 交换 s[i] 和 s[j] t = (s[i] + s[j]) % 256 result[k] = data[k] ^ s[t] # 进行按位异或操作 return result # 返回加密/解密后的字节数组 # 示例用法 key = b"mysecretkey" # 秘钥 data = bytearray(b"Hello, RC4!") # 加密数据 # 初始化 RC4 状态 s = rc4_init(key) # 加密或解密 encrypted_data = rc4_crypt(s.copy(), data) # 需要传递 s 的副本 print("加密后:", encrypted_data) # 再次初始化 RC4 状态 s = rc4_init(key) # 使用相同的状态解密 decrypted_data = rc4_crypt(s.copy(), encrypted_data) print("解密后:", decrypted_data.decode('utf-8'))
例题 1、
2、
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from Crypto.Cipher import ARC4 import binascii # 十六进制字符串 hex_data = "A71A68ECD82711CC8C9B16155CD2673E82ADCE75D4BC5756C28A52B86BD6CCF8A4BA722FE05715B92411" # 将十六进制字符串转换为字节 ciphertext = binascii.unhexlify(hex_data) # RC4 密钥(假设你知道密钥) key = b'RC4_1s_4w3s0m3' # 替换为你的RC4密钥 # 创建 RC4 解密对象 cipher = ARC4.new(key) # 解密数据 plaintext = cipher.decrypt(ciphertext) # 输出解密后的内容 print(plaintext.decode('utf-8', errors='ignore'))
2024省赛初赛复现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 ezRe (Python 3.9) [Code] File Name: flag_checker.py Object Name: <module> Arg Count: 0 Pos Only Arg Count: 0 KW Only Arg Count: 0 Locals: 0 Stack Size: 7 Flags: 0x00000040 (CO_NOFREE) [Names] 'base64' 'input' 'text' 'key' 'list' 'range' 's' 'j' 'i' 'len' 'data' '_' 'append' 'result' 'zip' 'c' 'k' 'chr' 'ord' 'b64encode' 'encode' 'decode' 'enc' 'print' [Var Names] [Free Vars] [Cell Vars] [Constants] 0 None 'Flag: ' '7e021a7dd49e4bd0837e22129682551b' [Code] File Name: flag_checker.py Object Name: <listcomp> Arg Count: 1 Pos Only Arg Count: 0 KW Only Arg Count: 0 Locals: 2 Stack Size: 4 Flags: 0x00000043 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE) [Names] 'ord' [Var Names] '.0' 'i' [Free Vars] [Cell Vars] [Constants] 102 [Disassembly] 0 BUILD_LIST 0 2 LOAD_FAST 0: .0 4 FOR_ITER 16 (to 22) 6 STORE_FAST 1: i 8 LOAD_GLOBAL 0: ord 10 LOAD_FAST 1: i 12 CALL_FUNCTION 1 14 LOAD_CONST 0: 102 16 BINARY_XOR 18 LIST_APPEND 2 20 JUMP_ABSOLUTE 4 22 RETURN_VALUE '<listcomp>' 256 50 1 '' 51 'w53Cj3HDgzTCsSM5wrg6FMKcw58Qw7RZSFLCljRxwrxbwrVdw4AEwqMjw7/DkMKTw4/Cv8Onw4NGw7jDmSdcwq4GGg==' 'yes!' 'try again...' [Disassembly] 0 LOAD_CONST 0: 0 2 LOAD_CONST 1: None 4 JUMP_FORWARD 0 (to 6) 6 JUMP_FORWARD 0 (to 8) 8 JUMP_FORWARD 0 (to 10) 10 IMPORT_NAME 0: base64 12 STORE_NAME 0: base64 14 LOAD_NAME 1: input 16 LOAD_CONST 2: 'Flag: ' 18 CALL_FUNCTION 1 20 STORE_NAME 2: text 22 LOAD_CONST 3: '7e021a7dd49e4bd0837e22129682551b' 24 STORE_NAME 3: key 26 LOAD_CONST 4: <CODE> <listcomp> 28 LOAD_CONST 5: '<listcomp>' 30 MAKE_FUNCTION 0 32 LOAD_NAME 3: key 34 GET_ITER 36 CALL_FUNCTION 1 38 STORE_NAME 3: key 40 LOAD_NAME 4: list 42 LOAD_NAME 5: range 44 LOAD_CONST 6: 256 46 CALL_FUNCTION 1 48 CALL_FUNCTION 1 50 STORE_NAME 6: s 52 LOAD_CONST 0: 0 54 STORE_NAME 7: j 56 LOAD_NAME 5: range 58 LOAD_CONST 6: 256 60 CALL_FUNCTION 1 62 GET_ITER 64 FOR_ITER 62 (to 128) 66 STORE_NAME 8: i 68 LOAD_NAME 7: j 70 LOAD_NAME 6: s 72 LOAD_NAME 8: i 74 BINARY_SUBSCR 76 BINARY_ADD 78 LOAD_NAME 3: key 80 LOAD_NAME 8: i 82 LOAD_NAME 9: len 84 LOAD_NAME 3: key 86 CALL_FUNCTION 1 88 BINARY_MODULO 90 BINARY_SUBSCR 92 BINARY_ADD 94 LOAD_CONST 6: 256 96 BINARY_MODULO 98 STORE_NAME 7: j 100 LOAD_NAME 6: s 102 LOAD_NAME 7: j 104 BINARY_SUBSCR 106 LOAD_NAME 6: s 108 LOAD_NAME 8: i 110 BINARY_SUBSCR 112 ROT_TWO 114 LOAD_NAME 6: s 116 LOAD_NAME 8: i 118 STORE_SUBSCR 120 LOAD_NAME 6: s 122 LOAD_NAME 7: j 124 STORE_SUBSCR 126 JUMP_ABSOLUTE 64 128 LOAD_CONST 0: 0 130 DUP_TOP 132 STORE_NAME 8: i 134 STORE_NAME 7: j 136 BUILD_LIST 0 138 STORE_NAME 10: data 140 LOAD_NAME 5: range 142 LOAD_CONST 7: 50 144 CALL_FUNCTION 1 146 GET_ITER 148 FOR_ITER 88 (to 238) 150 STORE_NAME 11: _ 152 LOAD_NAME 8: i 154 LOAD_CONST 8: 1 156 BINARY_ADD 158 LOAD_CONST 6: 256 160 BINARY_MODULO 162 STORE_NAME 8: i 164 LOAD_NAME 7: j 166 LOAD_NAME 6: s 168 LOAD_NAME 8: i 170 BINARY_SUBSCR 172 BINARY_ADD 174 LOAD_CONST 6: 256 176 BINARY_MODULO 178 STORE_NAME 7: j 180 LOAD_NAME 6: s 182 LOAD_NAME 7: j 184 BINARY_SUBSCR 186 LOAD_NAME 6: s 188 LOAD_NAME 8: i 190 BINARY_SUBSCR 192 ROT_TWO 194 LOAD_NAME 6: s 196 LOAD_NAME 8: i 198 STORE_SUBSCR 200 LOAD_NAME 6: s 202 LOAD_NAME 7: j 204 STORE_SUBSCR 206 LOAD_NAME 10: data 208 LOAD_METHOD 12: append 210 LOAD_NAME 6: s 212 LOAD_NAME 6: s 214 LOAD_NAME 8: i 216 BINARY_SUBSCR 218 LOAD_NAME 6: s 220 LOAD_NAME 7: j 222 BINARY_SUBSCR 224 BINARY_ADD 226 LOAD_CONST 6: 256 228 BINARY_MODULO 230 BINARY_SUBSCR 232 CALL_METHOD 1 234 POP_TOP 236 JUMP_ABSOLUTE 148 238 LOAD_CONST 9: '' 240 STORE_NAME 13: result 242 LOAD_NAME 14: zip 244 LOAD_NAME 2: text 246 LOAD_NAME 10: data 248 CALL_FUNCTION 2 250 GET_ITER 252 FOR_ITER 32 (to 286) 254 UNPACK_SEQUENCE 2 256 STORE_NAME 15: c 258 STORE_NAME 16: k 260 LOAD_NAME 13: result 262 LOAD_NAME 17: chr 264 LOAD_NAME 18: ord 266 LOAD_NAME 15: c 268 CALL_FUNCTION 1 270 LOAD_NAME 16: k 272 BINARY_XOR 274 LOAD_CONST 10: 51 276 BINARY_XOR 278 CALL_FUNCTION 1 280 INPLACE_ADD 282 STORE_NAME 13: result 284 JUMP_ABSOLUTE 252 286 LOAD_NAME 0: base64 288 LOAD_METHOD 19: b64encode 290 LOAD_NAME 13: result 292 LOAD_METHOD 20: encode 294 CALL_METHOD 0 296 CALL_METHOD 1 298 LOAD_METHOD 21: decode 300 CALL_METHOD 0 302 STORE_NAME 22: enc 304 LOAD_NAME 22: enc 306 LOAD_CONST 11: 'w53Cj3HDgzTCsSM5wrg6FMKcw58Qw7RZSFLCljRxwrxbwrVdw4AEwqMjw7/DkMKTw4/Cv8Onw4NGw7jDmSdcwq4GGg==' 308 COMPARE_OP 2 (==) 310 POP_JUMP_IF_FALSE 324 314 LOAD_NAME 23: print 316 LOAD_CONST 12: 'yes!' 318 CALL_FUNCTION 1 320 POP_TOP 322 JUMP_FORWARD 8 (to 332) 324 LOAD_NAME 23: print 326 LOAD_CONST 13: 'try again...' 328 CALL_FUNCTION 1 330 POP_TOP 332 LOAD_CONST 1: None 334 RETURN_VALUE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import base64 # 原始密钥和加密的目标输出 key = '7e021a7dd49e4bd0837e22129682551b' encoded_target = 'w53Cj3HDgzTCsSM5wrg6FMKcw58Qw7RZSFLCljRxwrxbwrVdw4AEwqMjw7/DkMKTw4/Cv8Onw4NGw7jDmSdcwq4GGg==' # 处理密钥 processed_key = [ord(i) ^ 102 for i in key] # RC4 类似的流密码算法构建 s = list(range(256)) j = 0 for i in range(256): j = (j + s[i] + processed_key[i % len(processed_key)]) % 256 s[i], s[j] = s[j], s[i] # 生成数据流 `data` i = j = 0 data = [] for _ in range(50): # 生成50个密钥流字节 i = (i + 1) % 256 j = (j + s[i]) % 256 s[i], s[j] = s[j], s[i] data.append(s[(s[i] + s[j]) % 256]) # 解码 `encoded_target` 并转换为原始字符串 target_bytes = base64.b64decode(encoded_target).decode() decoded_text = '' # 使用 `data` 对 `target_bytes` 进行解码 for c, k in zip(target_bytes, data): decoded_text += chr((ord(c) ^ k) ^ 51) print("Decoded text (flag):", decoded_text)
litctf-easyrc4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 __int64 __ fastcall rc4_crypt(__int64 a1, __ int64 a2, int i_ 2, __int64 a4) { __ int64 v4; // kr00_8 __int64 i_1; // rax int v8; // [rsp+30h] [rbp-10h] int v9; // [rsp+34h] [rbp-Ch] unsigned int i; // [rsp+38h] [rbp-8h] v8 = 0; v9 = 0; for ( i = 0; ; ++i ) { i_1 = i; if ( (int)i >= i_2 ) break; v8 = (v8 + 1) % 256; v4 = *(unsigned __ int8 *)(v8 + a4) + v9; v9 = (unsigned __int8)(HIBYTE(v4) + *(_BYTE *)(v8 + a4) + v9) - HIBYTE(HIDWORD(v4)); swap(v8 + a4, a4 + v9); *(_BYTE *)((int)i + a2) = *(_BYTE *)((unsigned __ int8)(*(_ BYTE *)(v8 + a4) + * (_BYTE *)(v9 + a4)) + a4) ^ *(_ BYTE *)((int)i + a1) ^ 0x20; } return i_1; }
plaintext[i] = cipher[i] ^ RC4_byte ^ 0x20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from Crypto.Cipher import ARC4 key = b"FenKey!!" cipher_hex = ( b'\x78\xCC\x4E\x13\x31\xF4\x73\x49' b'\x4F\x6C\x4F\x73\xC0\xF4\x35\x7E' b'\xCE\x27\x76\x4D\x19\x60\x7A\xEA' b'\x44\x5D\xC0\x42\x81\xDA\x1C\xF6' b'\x64\x72\x58\xD9\x94\xFA\xF8\x13' ) # 创建 RC4 加密器 rc4 = ARC4.new(key) # 获取 RC4 伪随机流 keystream = rc4.encrypt(b'\x00' * 40) # 解密:cipher ^ keystream ^ 0x20 plaintext = bytes([c ^ k ^ 0x20 for c, k in zip(cipher_ hex, keystream)]) print("Recovered flag:", plaintext.decode(errors='ignore'))
更新: 2025-05-25 10:14:54 原文: https://www.yuque.com/chaye-apqbl/vsc85q/flp109atxsuqmrpm