(五)序列密码

对称加密——序列密码(流密码)

工作原理

序列密码先通过密钥产生一个伪随机序列,然后用这个伪随机序列与明文进行异或运算以产生密文序列,它和一次一密体制的加密原理相同。

相比于伪随机数发生器(PRNG),序列密码更类似于确定性随机比特发生器(DRBG)。和DRBG一样,序列密码是确定性的。这保证了使用者能够重新产生加密序列并用以解密。而PRNG可以实现加密,但无法解密,所以没有用途。

序列密码有两个输入参数:密钥和nonce(有时作为初始值,符号为IV)。密钥需要保密,通常为128比特或256比特。而nonce是公开参数,长度一般在64比特和128比特之间。但在使用时需要注意,nonce不一定是秘密的,但是对于每个密钥它应该是唯一的。

序列密码的密钥序列对密文进行异或即可解密回明文。

序列密码加密过程

上图所示的是序列密码加密过程,其中

SC代表序列密码算法,K是密钥,N是nonce,KS是密钥序列,P是明文,C是密文。

序列密码计算KS=SC(K,N),加密时计算C=P⊕KS,解密时计算P=C⊕KS。加密函数和解密函数运算是相同的,都是与密码序列进行异或运算,只是输入不同。加密函数可同时用来加密和解密。

现在通过一个秘密的密钥K和一个nonce N来对一段消息进行加密。当需要对另外一段消息进行加密时,要么更换K,要么更换N。否则,算法将产生相同的密钥序列KS,由此可以得到两组密文C1 = P1⊕KS和C2 = P2⊕KS。若已知P1,则可以得到P2 = C1⊕C2⊕P1。此时算法已被破解。

基于状态的序列密码

基于状态的序列密码有一个秘密的内部状态,它在整个密钥序列产生的过程中不断演化。这个秘密的内部状态是由密钥和nonce经过初始化得到的,序列密码则通过状态更新函数去更新状态以产生一个或多个密钥系列比特。

RC4算法就是一种基于状态的序列密码。

基于状态的序列密码

基于计数器的序列密码

基于计数器的序列密码通过密钥、nonce和计数器来产生密钥序列,基于计数器的序列密码在密钥序列生成过程中不需要记忆任何秘密状态。

Salsa 20算法就是基于计数器的序列密码。

基于计数器的序列密码

面向硬件的序列密码

密码的硬件实现是一个电子电路,它用以实现比特级别的密码算法,这个电路是专用硬件,由一系列逻辑门电路及其他线路组成,不能用于其他用途;

面向硬件的序列密码的基本机制:反馈移位寄存器

 反馈移位寄存器(FSR)

FSR包含由一些比特构成的数组以及一个更新的反馈函数(记为f)。FSR的状态存储在数组或寄存器中,每次更新就是使用反馈函数改变状态并产生一个输出比特。

FSR作工原理如下:

设FSR的初始状态是R0,它的下一个状态R1是由状态R0左移1比特后,最右侧的空位由f(R0)补充而得到的。这时,左侧移出的比特就作为FSR的输出比特。按照同样的规则,可以依次得到接下来的状态R2、R3等。也就是说,给定FSR在t时刻的状态Rt,下一时刻的状态R(t+1)为:

R(t+1) = (Rt << 1) | f(Rt)。

现在考虑4比特的FSR反馈函数f=L1⊕L2⊕L3⊕L4,(Li代表第i个比特)

设初始状态为R1 = 1100,

R2=R1<<1 | f(R1)=1100<<1 | (1⊕1⊕0⊕0)=1000,输出比特为1。

R3=R2<<1 | f(R2)=1000<<1 | (1⊕0⊕0⊕0)=0001,输出比特为1。

R4=R3<<1 | f(R3)=0001<<1 | (0⊕0⊕0⊕1)=0011,输出比特为0。

R5=R4<<1 | f(R4)=0011<<1 | (0⊕0⊕1⊕1)=0110,输出比特为0。

R6=R5<<1 | f(R5)=0110<<1 | (0⊕1⊕1⊕0)=1100,输出比特为0。

经过5次迭代R6=R1,结论是从上面R1~R5任意一个状态开始,经过5次迭代都将回到初始状态,称它们的周期为5。假设初始为1100,运行15次,输出序列为11000110001100011000

所以,FSR实质上是基于比特的寄存器。每经过一次更新,寄存器输出最左比特,同时,通过更新f函数计算新的值 赋给最右侧比特,寄存器的其他位置左移。给定初始状态,FSR的周期就是回到初始状态所需的更新次数。

线性反馈移位寄存器(LFSR)

LFSR是具有线性反馈函数的FSR,即反馈函数仅仅是状态的某些比特位相异或。

上面的4比特异或的FSR就是一个LFSR的例子。

影响LFSR的周期的关键是选取状态的哪些位置的比特相异或。记最右侧比特的位置记为1,最左侧比特的位置记为n,将位置信息转化为多项式1+X+X^2+…+X^n,其中X^i项当且仅当寄存器的第i位置的比特参与反馈函数的异或运算时出现。寄存器达到最大周期的条件是当且仅当上述形式的多项式是本原的(数学概念)。多项式具有本原性必须满足以下条件:

1.该多项式必须是不可约的,这意味着它不能被因式分解,也即不能表示为一些多项式的乘积。例如,多项式X+X^3不是不可约多项式,因为它等于(1+X)(X+X^2)。

2.该多项式必须满足其他一些数学性质(比较复杂,后面补充)。

一个n比特LFSR的最大周期是2^n−1,而不是2^n,这是因为全0状态经过寄存器更新会回到本身。因为反馈函数是若干位置的0相异或,这个反馈值为0,所以全0状态经过左移和反馈更新后仍是全0状态。

下图考虑一个4比特LFSR,反馈多项式为1+X+X^3+X^4,即位置为1、3和4的比特参与异或运算生成新的反馈比特L1。该寄存器的多项式不是本原的,它可以分解为(1+X^3)(1+X)。

它的周期没有达到最大值15。

再来考虑反馈多项式为1+X^3+X^4的情况,这是本原多项式,该寄存器周期达到最大值15。

不过,在序列密码中使用LFSR并不安全。若一个LFSR的长度为n,攻击者仅仅需要n比特输出就可以还原该寄存器的初始状态,这样就可以反推之前的状态信息并得到之后的输出序列。这个攻击基于Berlekamp-Massey算法(简称为BM算法)。攻击者甚至不需要提前知道寄存器的长度n,可以用BM算法穷举所有可能的长度来实施攻击。

提高LFSR的安全性

为了掩盖LFSR的线性性质,可以对LFSR的输出序列进行非线性过滤以得到非线性程度更高的密钥序列,这被称为过滤生成器

下图所示的函数g必须是非线性函数——变量相异或 进行 逻辑与 及逻辑或操作。例如,L1×L2+L3×L4(多项式为1+XX^2+X^3X^4)是一个非线性函数(×是逻辑与,+是逻辑或)

即便如此,LFSR也仍然会被更复杂的数学计算攻破。

非线性反馈移位寄存器(NFSR)

非线性反馈移位寄存器(NFSR)和LFSR类似,不过NFSR的反馈函数使用非线性函数。这说明,寄存器反馈函数中会进行异或、逻辑与和逻辑或等运算。

设一个4比特的NFSR初始状态R0=(N1,N2,N3,N4),反馈函数f=(N1+N2+N1×N2+N3×N4);

R1=R0<<1 | (N1 + N2 + N1×N2 + N3×N4)=(N1+N2+N1×N2+N3×N4,N1,N2,N3);

R2=R1<<1 | ((N1+N2+N1×N2+N3×N4)+N1+(N1+N2+N1×N2+N3×N4)×N1+N2×N3)

=((N1+N2+N1×N2+N3×N4)+N1+(N1+N2+N1×N2+N3×N4)×N1+N2×N3,N1+N2+N1×N2+N3×N4,N1,N2)

从上面可以看出,通过非线性反馈函数的迭代能够指数级增加方程的规模。

不过,目前还没有有效的方法给出给定NFSR的周期,或者判断它的周期是否达到最大,对一个n比特的NFSR,几乎需要做2^n次试验才能验证它的周期是否最大。

Grain-128a算法

Grain算法是面向硬件实现的算法之一,Grain-128a算法是Grain算法的一个升级版本。

它包括一个128比特的LFSR、一个128比特的NFSR和一个过滤函数h。该LFSR周期达到最大,即2^128−1,而这种LFSR到NFSR的串联结构保证了输出序列的周期至少是2^128−1。同时,NFSR和非线性过滤函数h也增加了密码强度。

Grain-128a算法使用128比特密钥和96比特的nonce。

首先,将128比特密钥填充至NFSR的128比特寄存器中,将96比特的nonce填充至LFSR的前96比特中,LFSR的中间31比特填1,最右比特填0。

接下来的初始化阶段,系统将运行256次后输出第一个密钥比特。在初始化阶段,经非线性过滤函数h作用后得到的比特并不输出,而是反馈到LFSR,用来保证寄存器的状态既依赖密钥也依赖nonce。

LFSR的反馈函数是:f(L) = L32+L47+L58+L90+L121+L128,这个反馈函数是本原多项式。

NFSR的反馈函数是:g(N) = N32+N37+N72+N102+N128

+N44×N60+N61×N125+N63×N67+N69×N101+N80×N88+N110×N111+N115×N117

+N46×N50×N58+N103×N104×N106+N33×N35×N36×N40。

这个函数经过精心挑选以同时兼顾其密码性质和实现效率。它的代数次数是4,变量的最多的项有4个变量(N33×N35×N36×N40)。

过滤函数h也是一个非线性函数;它挑选了NFSR的9个比特和LFSR的7个比特作为输入。

Grain-128a算法通常被用于某些低端嵌入式系统。

Grain-128a工作原理图

A5/1算法(已被攻破)

之前A5/1算法是2G移动通信标准,用于对语音通信进行加密,但现在已被破解。

A5/1算法由三个LFSR组成,三个LFSR的长度分别为19、22和23,寄存器的反馈多项式分别为:

1+X^14+X^17+X^18+X^19

1+X^21+X^22

1++X^8+X^21+X^22+X^23

A5/1算法原理图

 A5/1算法中使用的三个LFSR并非每一时刻都输出,而是通过下面的钟控规则来决定每个寄存器的停走。(由于线性性质决定,如果同步输出就不安全了)

1.分别选取第一个寄存器的第9位置的比特、第二个寄存器的第11位置的比特和第三个寄存器的第11位置的比特作为钟控比特。在上述三个比特位中,或者三个取值都相同,或者有两个取值相同。

2.钟控比特按择多原则取值0或1。当钟控比特与择多函数值一致时寄存器前进一拍,否则寄存器保持当前状态不动。由择多原则可知每次有2个或3个寄存器前进。

针对A5/1算法的攻击主要有以下两类。

细致攻击:挖掘算法内部的线性性质并利用它相对简单的钟控系统。这里采用了猜测确定攻击(穷举),即攻击者猜测一些内部状态比特以确定其他状态比特的攻击方法。

野蛮攻击:只利用A5/1算法的短密钥和帧数变换的可逆性。时间内存折中(TMTO)攻击是针对A5/1算法的野蛮攻击。该攻击不关心A5/1算法的内部状态,只关心它的内部状态是64比特长。TMTO攻击将A5/1算法当作一个64比特输入(内部状态)到64比特(前64比特密钥序列)输出的黑盒。

面向软件的序列密码

软件序列密码并不是基于比特运算的,而是基于字节或32/64比特字运算的。在现代CPU中,基于字和基于比特的算术运算操作所花费的时间成本相当,因此软件序列密码的实现效率更高。相对于硬件序列密码,软件序列密码更适合在个人计算机中运行的服务器或浏览器。在那里,软件序列密码被强大的通用处理器作为本地软件来运行。

最流行的序列密码之一实际上是基于分组密码的计数模式(CTR)的AES算法。

此外还有RC4,Salsa20。

RC4 (已被攻破)

RC4由RSA安全公司的Ron Rivest设计,应用广泛,著名的应用有:第一代WiFi加密标准无线等效协议(WEP,已被攻破)以及用于建立HTTPS连接的传输层安全性(TLS)协议。

RC4的内部状态是一个256字节的数组,记为S,初始赋值S[0]=0,S[1]=1,S[2]=2,…,S[255]=255,然后n字节的密钥K通过密钥编排方案(KSA)进行初始化。一旦KSA结束,数组S的所有字节的值域仍然是0~255,但是顺序看起来很随机。

给定初始状态S,RC4产生一个和明文P等长的密钥序列KS,以便计算密文C=P⊕KS

设明文P的长度为m字节,秘钥序列KS由如下python代码得到:

i = 0
j = 0
# 明文长度为m字节
for b in range(m):
    i = (i + 1) % 256
    j = (j + S[i]) % 256
    # 交换两个位置的值
    S[i], S[j] = S[j], S[i]
    KS[b]=S[(S[i] + S[j]) % 256]

RC4的秘钥编排方案 

# RC4的KSA秘钥编排方案
j = 0
# 设置256大小的S数组
S = range(256)
# 遍历S数组
for i in range(256):
    # 计算v
    j = (j + S[i] + K[i%n]) % 256
    # 交换S[i]和S[j]
    S[i], S[j] = S[j], S[i]

Salsa20 

Salsa20是一个基于计数器的序列密码算法,由著名的密码学家Daniel J.Bernstein设计。通过重复对每一个分组加入新的计数来生成它的密钥序列,它的实现非常简单和快速。

Salsa20核心算法使用密钥(K)、nonce(N)和计数器的数值(Ctr)来变换一个512比特的分组。

Salsa20原理图

Salsa20的核心置换使用了一个名为Quarter-Round(QR)的函数,该函数对4个32比特字(a、b、c和d)进行变换(从上到下计算):

b = b[(a + d) <<< 7]

c = c[(b + a) <<< 9]

d = d[(c + b) <<< 13]

a = a[(d + c) <<< 18]

操作<<<是基于字的指定位数的左循环移位,该位数可以是1到31之间的任何值(32比特字),例如:0x01234567 <<< 8 = 0x23456701。

Salsa20的核心置换针对512比特的内部状态,在变换时将这512比特的内部状态视为4×4的32比特字的阵列。

下图表示salsa20使用256比特的密钥(8个比特字,k0~k7)、64比特的nonce(2个比特字,v0~v1)、64比特的计数器(2个比特字,t0~t1)和128比特的常数字(4个比特字,c0~c3)填充的一个内部状态。常数对于每次加密/解密和所有分组都是唯一的。

Salsa20首先对4列分别独立地进行QR变换(称为列轮),然后对4行做变换(称为行轮)。序列的列轮/行轮被称为双轮。Salsa20共进行10次双轮,也就是共20轮,这也是Salsa20里有个20的原因。

变换4列:

QR(x0,x4,x8,x12)

QR(x1,x5,x9,x13)

QR(x2,x6,x10,x14)

QR(x3,x7,x11,x15)

每一列都是从上到下取值

变换4行:

QR(x0,x1,x2,x3)

QR(x5,x6,x7,x4)

QR(x10,x11,x8,x9)

QR(x15,x15,x13,x14)

第i行取第i个作为第一个元素。

 salsa20的安全性

下图是密钥全是0比特和nonce全是1比特的salsa20的状态,左边和右边只有一个比特不同(黑体部分)。

对左右两组进行差分密码分析(两组做XOR运算)

第一轮之后

 第二轮之后

第三轮之后

 

 第四轮之后

可以看出差分会慢慢完全扩散到512比特的绝大多数中。由于变换函数是异或、加法和乘法的混合,使得状态通过高度的非线性方程得以不断进化更新,使得未来的差分难以预测。

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值