典型序列密码算法之RC4
一、RC4 算法介绍
RC4
是由麻省理工学院的 Rivest 开发的,他也是RS4
的开发者之一。RC4
的突出优点是在软件中很容易实现。RC4
可能是世界上使用最广泛的序列密码,它已应用于 MicrosoftWindows、Lotus Notes 和其他软件应用程序中,应用于安全套接字层(SSL,Secure SocketsLayer)以保护因特网的信息流,还应用于无线系统以保护无线链路的安全等。
RC4
是一个典型的基于非线性数组变换的序列密码。它以一个足够大的数组为基础,对其进行非线性变换,产生密钥序列,一般把这个大数组称为 S
盒。RC4
的S
盒大小随参数n
的值变化而变化,理论上来说,S
盒长度为 $N=2^n$”个元素,每个元素n
比特。通常n=8
,这也是本书示例所选取值,此时,生成共有$ 256(=2^8)$个元素的数组 S
。RC4
包含两个处理过程:一个是密钥调度算法(KSA
,Key-Scheduling Algorithm),用来置乱S
盒的初始排列;另一个是伪随机生成算法(PRGA
,Pseudo RandomGeneration Algorithm)用来输出随机序列并修改S
的当前排列顺序
流程
KSA
首先初始化S
,即S[i]=i(i=0~255)
,同时建立一个临时数组向量T(|T|=256)
,如果种子密钥K
的长度为256
字节(|K|=256
),则直接将K
赋给T
,否则,若种子密钥K
的长度(记为|K|
)小于|T|
,则将K
的值赋给T
的前|K|
个元素,并不断重复加载K
的值直到T
被填满。这些操作可概括如下:
1 | for i := 0 to 255 do |
- 然后用
T
产生S
的初始置换,从S[O]
到S[255]
,对每个S[i]
,根据T
的值将S[i]
与S
中的另一个字节对换。概括如下:
1 | j:=0; |
- 因为对
S
的操作仅是交换,所以唯一的改变就是位置,S
仍然遍历0~255
的所有元素最后,利用PRGA
生成密钥流。从S
中随机选取一个元素输出,并置换S
以便下一次取,选取过程取决于索引i
和j
,下面描述选取密钥序列的过程:
1 | i,j:=0 |
- 加密时,将
k
的值与明文字节异或;解密时,将k
的值与密文字节异或。
RC4 的逻辑结构(例子)
- 下面以元素长为
3
比特(即n=3
)的RC4
为例来演示它的工作过程。显然,3
位RC4
的所有操作是对$2^3=8$取模。数组 S 只有$2^3=8$个元素,初始化为:
- 接着选取一个密钥,该密钥是由
0~7
的数以任意顺序组成的。例如,选取5、6、7
作为密钥。该密钥如下填人临时数组T
中:
- 然后执行
S
数组的初始置换,以i=0
和j=0
开始。使用更新公式后,j
为:
$$
\begin{aligned}
j &= [0 + S(0) + T(0)](mod 8) \
& = (0 + 0 + 5) mod 8 \
& = 5
\end{aligned}
$$
- 因此,
S
数组的第一个操作是将S(0)
与S(5)
互换
- 索引
i
加1
后,j
的下一个值为:
$$
\begin{aligned}
j &= [5 + S(1) + T(1)](mod 8) \
& = (5 + 1 + 6) mod 8 \
& = 4
\end{aligned}
$$
- 即将
S
数组的S(1)
与S(4)
互换:
- 当该循环执行完后,数组
S
就被随机化:
- 下面数组
S
就可以用来生成随机数序列了。从j=0
和i=0
开始,RC4
计算第一个随机数的过程如下:
$$
i = (i + 1) mod 8 = (0 + 1) mod 8 = 1 \
j = [j + S(i)]mod 8 = [0 + S(1)]mod 8 = [0 + 4]mod 8 = 4\
swap(S(1), S(4))
$$
- 然后计算和
k
:
$$
t=[S(j)+S(i)]mod8 =[S(4)+S(1)]mod 8=(1+4)mod8=5\
k=S(t)=S(5)=6
$$
- 第一个随机数为
6
,其二进制表示为110
。反复进行该过程,直到生成的密钥序列长度等于明文的长度。
二、C++代码
代码
核心代码上面的伪代码给过了,这里直接带进去就行了( ̄︶ ̄)↗
1 |
|
结果
1 | 请输入明文 |
三、小结
- 加密时,将
k
的值与明文字节异或;解密时,将k
的值与密文字节异或。 - 为了保证安全强度,目前的
RC4
至少使用128
位密,以防止穷举搜索攻击。 RC4
算法可看成一个有限状态自动机,把S
表和索引的具体取值称为RC4
的一个状态:$T=(S_0,S_1…S_{255},i,j)$。对状态T
进行非线性变化,产生出新的状态,并输出密钥序列中的一个字节k
,大约有$ 2^{1700}(256! \times 256^2)$种可能状态。- 用大的数据表
S
和字长来实现这个思想是可能,如可定义16
位RC4
。