流密碼的定義
流密碼(英語:Stream cipher)是一種對稱密鑰加密算法,它將明文消息按字符或比特逐位進行加密。加密方式基于異或的加密算法。
流密碼也稱為序列密碼。
流密碼的原理
首先,通信雙方需要協商并確定一個共享的密鑰。這個密鑰是保密的,只有通信雙方知道。同時,可能還會選擇一個初始化向量,它通常是公開的,但要保證每次加密時使用的初始化向量不同,以增加密碼的安全性。
將明文消息與密鑰流進行逐位的異或運算,得到密文。由于密鑰流是偽隨機的,且與明文消息長度相同,所以對于每一位明文,加密時都使用了不同的密鑰流位,從而增加了密碼的安全性。

將明文消息逐位與生成的密鑰流進行異或運算。例如,對于明文比特流P = p1p2p3...pn和密鑰流K = k1k2k3...kn,密文C = c1c2c3...cn,其中ci = pi ⊕ ki(⊕表示異或運算)。這樣,每一位明文都與對應的密鑰流位進行異或,得到密文。
加密流程如下圖所示:

為什么需要一次一密?
流密碼常見的問題如果多次使用相同秘鑰進行加密,攻擊者可以不使用密碼也可以獲得密文。
流密碼如何防止恢復密鑰流?
流密碼的安全性依賴于密鑰流的隨機性和不可預測性。如果密鑰流能夠被攻擊者預測或分析出來,那么密文就很容易被破解。
RC4算法的簡介
RC4 算法是一種流密碼算法,是一種可變密鑰長度的流密碼,它的密鑰長度可以在 1 到 256 字節之間變化。
加密流程用文字說明太繞,直接跟著調試器看代碼吧!
CODE:
def crypt(data, key): # data為明文或密文,key為密鑰
"""RC4 algorithm"""
x = 0
# box = range(256) #初始化S盒
box = list(range(256)) # 使用 list(range(256)) 創建可修改的列表
for i in range(256):
x = (x + box[i] + ord(key[i % len(key)])) % 256
box[i], box[x] = box[x], box[i]
x = y = 0
out = []
for char in data:
x = (x + 1) % 256
y = (y + box[x]) % 256
box[x], box[y] = box[y], box[x]
out.append(chr(ord(char) ^ box[(box[x] + box[y]) % 256]))
# 對稱密碼,加密解密算法一樣
return ''.join(out)
# 加密
encrypted_str = crypt("Hello", "123") # 假設返回字符串
encrypted_bytes = encrypted_str.encode("latin-1") # 轉字節(確保無損)
hex_result = encrypted_bytes.hex() #轉16進制 .hex()
print("加密結果:", hex_result)
# 解密
decrypted = crypt(bytes.fromhex(hex_result).decode("latin-1"), "123")
print("解密結果:", decrypted)
S盒是什么?
在 RC4 算法中,S 盒是一個長度為 256 的字節數組,用于存儲和操作加密過程中的數據。
作用:
-
打亂數據順序:S 盒的主要作用是通過特定的初始化過程,將其內部的元素順序打亂。這個打亂過程基于密鑰進行,使得 S 盒的狀態與密鑰相關聯。這樣,不同的密鑰會導致 S 盒具有不同的初始狀態,從而為加密提供了不同的 “混淆” 方式,增加了密碼的安全性。
-
生成密鑰流:在密鑰流生成階段,通過對 S 盒的操作來生成偽隨機的密鑰流字節。算法根據特定的規則對 S 盒進行索引和元素交換,然后根據 S 盒的狀態計算出密鑰流字節。由于 S 盒的狀態是由密鑰決定的,所以生成的密鑰流也與密鑰緊密相關,并且具有一定的隨機性和不可預測性。
-
純線性操作易被破解(如線性密碼分析),非線性變換(如 S 盒)可增加復雜度。
初始化代碼:
for i in range(256):
x = (x + box[i] + ord(key[i % len(key)])) % 256
box[i], box[x] = box[x], box[i]
初始化的S盒:

規律:S盒基于秘鑰生成,同一個秘鑰所生成的S盒都是一樣的。
取模介紹
取模運算,也叫取余運算,其原理是在整數除法中,被除數不能被除數整除時,就會產生余數,這個余數就是取模運算的結果。
被除數 小于 除數時,余數是被除數。
代碼: x = (x + box[i] + ord(key[i % len(key)])) % 256 中,% 256 是 取模運算,它的核心目的是確保計算結果 x 的值始終落在 0 到 255 的范圍內。
加密、解密


復用庫的RC4用法
python中Crypto庫中有該算法,具體用法如下:
from Crypto.Cipher import *
data = "kangel"
key = "key"
cipher = ARC4.new(key) #加載密鑰
m = cipher.decrypt(key) #用該密鑰解密
print m
總結
總而言之就是兩個步驟:
- 基于秘鑰生成一個256位的S盒;
- 逐個將明文與S盒內的某位數做異或操作。
Reference
逆向踩坑之RC4
https://j-kangel.github.io/2019/04/09/RC4/#簡介
浙公網安備 33010602011771號