【密码学】DES、AES、RC4

对称密码

  • 数据加密标准
  • 高级加密标准
  • 分组密码的工作模式
  • 伪随机数的产生和流密码

数据加密标准

DES

  1. 明文m(64bit)的位通过一个固定的初始置换进行置换,得到m0 = IP(m)。记做m0 = L0R0。L0为m0的前32位,R0为m0的后32位。
  2. 对1<=i<=16,执行操作:*Li=R(i-1) Ri=L(i-1)⊕f(R(i-1),Ki)*其中Ki是从K得到的48位的串,f是一个函数
  3. 左右交换,得到R16L16,用初始置换的逆作用得到密文c=IP^(-1)(R16L16)
  • 初始置换:可以描述成一个初始置换表
  • 函数f(R,Ki)
    • R通过扩展置换表扩展成E®,注意E®有48位。
    • 计算E®⊕Ki,将48位分成B1B2……B8,其中Bj有6bit。
    • 有8个S盒,Bj是Sj的输入。记Bj=b1b2b3b4b5b6。b1b6确定S盒的行,b2b3b4b5确定S盒的列,按此方式得到八个4位的输出C1,C2,……,C8。
    • C1,C2,……,C8根据下表做置换。
    • 得到的32位结果就是f(R,Kj)
  • 如何得到K1,K2,…,K16,我们是从64位的密钥K开始的。
    • 丢掉校验位,其余位用密钥置换表做置换,结果写为C0D0,其中C0D0都是28bit。
    • 对1<=i<=16,令Ci=LSi(C(i-1)),Di=LSi(D(i-1))。这里的LSi是根据下表对输入左移1或2个位置。
    • 根据下表,从56位的串CiDi中选取48位的串,输出是Ki

高级加密标准:Rijndael

Rijndael的结构

Rijndael的密钥长度有128位、192位、256位3种。通用的设计准则:可逆性:所有步骤是可逆的;简单性:避免复杂组件。Rijndael算法由十轮组成(192位12轮,256位14轮),每一轮有一个原始密钥生成的轮密钥,还有一个第0轮的密钥,就是原始密钥。每一轮输入输出都是128bit。每一轮都有四个基本步骤

  1. ByteSub变换(BS):一个非线性层,目的是抵抗差分和线性攻击。
  2. ShiftRow变换(SR):一个线性层,目的是经过多轮的作用对位进行混淆。
  3. MixColumn变换(MC):目的与SR相似。
  4. AddRoundKey(ARK):这一轮的轮密钥和上述层的结果做异或。
  • ARK,使用第0轮的轮密钥。
  • 9轮的BS,SR,MC,ARK,使用第一轮至第九轮的轮密钥。
  • 最后一轮:BS,SR,ARK,使用第十轮的轮密钥(第十轮密钥用到MC。
Rijndael(state, CipherKey)
{//使用Rijndael进行加密的高级算法
	KeyExpansion(CipherKey,ExpandedKey);
	AddRoundKey(State,ExpandedKey[0]);//ARK为初始密钥加法
	For(i = 1; i <= Nr; i++)
		Round(State, ExpandedKey[i]);
	FinalRound(State,ExpandedKey[Nr]);//最后使用轮变换FinalRound
	}
//Rijndeal的轮变换
Round(State,ExpandedKey[i])
{
	SubBytes(state);
	ShiftRow(state);
	MixColumn(state);
	AddRoundKey(State,ExpandedKey[i]);
	}
FinalRound(State,ExpandedKey[Nr])
{
	SubBytes(States);
	ShiftRows(States);
	AddRoundKey(State,ExpandedKey[Nr]);
	}	

轮变换

  • 步骤SubBytes:砖匠置换,包含一个作用在状态字节上的S-盒,用Srd表示。
    • Srd的设计准则:
      • 非线性度
        • 相关性:输入-输出之间的最大相关幅度必须尽可能小
        • 差分传播概率的最大值必须尽可能小
      • 数复杂度:在GF(2^8)中Srd应该具有复杂的代数表达式
    • Srd的选择:构造为g和一个可逆仿射变换f的序列。
      • g : a -> b = a^(-1)
      • 仿射变换f可描述为:先进行多项式乘法,然后再与一个常量异或。
  • 步骤ShiftRows:字节换位
    • 设计准则:
      • 最佳扩散性:4个偏移量必须互不相同
      • 其他扩散效果:抗击截短差分攻击和渗透攻击的能力必须最大
    • 偏移量的选择:
      • 对于128bit分组,偏移量的值选0,1,2,3,各行使用其中任意一个
      • 各种偏移量的选择并非完全等价
  • 步骤MixColumn:作用在状态各列的砖匠置换
    • 设计准则:
      • 维度:该变换是一个作用在4字节列上的砖匠变换。
      • 线扩性:该变换是GF(2)上的线性变换。
      • 扩散性:改变换需要有相应的扩散能力。
      • 在8位处理器上的性能
    • 选取:
      • 扩散性和性能选择使D-盒的定义:将状态的列看做GF(28)上的多项式,并在模x4+1下与一个给定的多项式c(x)相乘。
      • 多项式c(x)=03x3+01x2+01x+0.它与x^4+1互素,是可逆的。
      • 因为与一个固定的多项式模乘可表示为一个矩阵乘法。设b(x)=c(x)*a(x)(modx^4+1)。
  • 密钥加法:
    • 状态的调整通过与一个轮密钥进行逐位异或而得到。轮密钥记做ExpandedKey[i]。
    • 轮密钥ExpanedKey由密码密钥通过密钥编排方案导出,轮密钥长度等于分组长度。ARK的逆仍是其自身。

轮的数目

  • 迭代型分组密码抗击密码分析攻击的能力随轮数的增加而增加。
  • 考虑抗击捷径攻击来确定轮的数目,在此基础上增加了一个适当的安全余量。对分组长度和密钥长度均是128bit的Rijndael,并未发现对具有六轮以上的简化版本实施的捷径攻击,又增加了4轮作为安全余量。这是一个保守的做法因为:
    • Rijndael中两轮即可提供以下意义的“全扩散”。每个状态比特均依赖于两轮前的所有状态比特,或者一个状态比特的改变均可能对两轮之后的半数状态比特产生影响。再增加四轮可以看作是在密码的开始和结束时增加了一个“全扩散步骤”。Rijndael轮变换的高扩散性归功于它再所有状态比特上的均匀结构。
    • 为了攻击密码的第n+1轮或n+2轮,线性密码分析、差分密码分析和截短差分攻击通常采用一个直到n轮的传播轨迹。渗透攻击也是如此,它利用一个四轮的传播结构来攻击六轮。在这方面,增加四轮实际上使得找到一个传播轨迹所遍历的轮数增加一倍。
  • 对于较长密钥的Rijndael,密码密钥每增加32bit,轮的数目增加一轮。
    • 主要目的之一是使比穷举密钥搜索攻击更加有效的捷径攻击失效。
    • (部分)已知密钥和相关密钥攻击利用了密码密钥中的比特信息,或者具有利用不同密码密钥的能力。如果增加密钥长度,密码分析者的搜索范围会增加
    • 如果密码分组长度大于128bit,就采用三轮来实现全扩散,因为轮变换的罗三能力随着分组长度的增加而变低。
    • 更大的分组长度将增加可能出现的模式的选取范围,这些模式可用在某几轮的输入输出上。这一附加的灵活性可使攻击所必须处理的范围扩大一轮或更多轮。

密码编排方案

密钥的编排方案包括两部分,即密钥的扩展和轮密钥的选取。密钥的扩展是指如何由密码密钥得到ExpandedKey.由于改密码要求一个轮密钥用于初始密钥加法,而且每轮都需要一个轮密钥,因此ExpandedKey中的全部比特数等于分组长度乘以轮数加一。注意ExpandedKey总是由密码密钥导出,从不被直接指定。

  • 设计准则

    • 效率
      • 工作内存:应当能用少量的工作内存来执行密钥编排方案
      • 性能:多种处理器上均应具有高性能
    • 对称消除:应使用轮常量来消除对称性
    • 扩散:应将密码密钥的差分有效的扩散到扩展密钥中
    • 非线性性:避免扩展密钥中的差分仅由密码密钥的差分完全决定
  • 128位原始密钥的扩展

    • 开始的4列为W(0),W(1),W(2),W(3),新的列递归生成。
      • i不是4的倍数:W(i) = W(i - 4)⊕W(i - 1)
      • i是4的倍数:W(i) = W(i - 4)⊕T(W(i - 1))(TT(W(i - 1))是对W(i-1)的变换)
        • 记列W(i-1)中的元素为a,b,c,d,循环移位得到b,c,d,a。
        • 将这些字节用S-盒相应的元素替代,得到4个字节e,f,g,h,
        • 计算有限域GF(2^8)中的常亮: r ( i ) = 0000001 0 ( i 4 ) / 4 r(i) = 00000010^{(i-4)/4}
        • 那么T(W(i - 1))是如下列向量:(e⊕r(i),f,g,h)
    • 第i轮的轮密钥:W(4i),W(4i+1),W(4i+2),W(4i+3)

S盒的构成

S盒简单的数学描述。输入一个字节x7x6x5x4x3x2x1x0,其中每一个xi都是一个二进制的位。先计算它在GF(2^8)中的逆,如果字节是00000000,就没有逆,用00000000来代替逆。得到的字节y7y6y5y4y3y2y1y0可以看成一个八维的列向量,最右边的位y0在最高的位置。将这个向量左乘一个矩阵,再加上列向量(1,1,0,0,0,1,1,0),得到(z0,z1,z2,z3,z4,z5,z6,z7)。字节(z7,z6,z5,z4,z3,z2,z1,z0)是S盒中的一项。

S盒考虑了以下问题:映射x->x^(-1)是一个非线性的变换,但简单的一个映射不足以抵抗某些攻击,所以还要乘以一个矩阵加上一个列向量。选择这样一个矩阵因为它形式简洁,列向量的选择是因为防止S盒的输入和输出相同或互反。

解密算法

  • ByteSub、ShiftRow、MixColumn和AddRoundKey每一步都是可逆的
  • ByteSub的逆是另一个查找表,叫InvByteSub。
  • ShiftRow的逆是将行右移而不是左移,得到InvShiftRow。
  • Mixcolumn的逆存在因为MixColumn中用的矩阵是可逆的。InvMixColumn变化通过乘以一个矩阵。
  • AddRoundKey的逆是它自身

解密算法可以直接利用步骤InvByteSub、InvShiftRow、InvMixColumn和AddRoundKey的逆并倒置其次序得到,成为直接解密算法。在这个算法中,不仅步骤本身和加密不同,而且步骤出现的顺序也不相同。注意到,先BS后SR和先SR后BS是一样的,因为BS一次作用于一个字节,而SR是对多个字节位置的替换。同样的,ISR和IBS的先后次序也是可以交换的。我们想同时交换ARK和IMC的次序但是行不通,经过研究我们在解密中可以用先IMC后IARK来代替先IARK后IMC。

  1. ARK,使用第十轮的轮密钥。
  2. 九轮的IBS、ISR、IMC、IAPK,使用第九轮到第一轮的密钥。
  3. 最后一轮:IBS、ISR、ARK、使用第0轮的密钥。
  • 8位处理器上,解密速度不如加密速度快,因为InvMixColumn的4x4矩阵比MixColumn的4x4矩阵的项要复杂一些
  • 加密过程最后一轮省略了MixColumn:考虑到解密算法,影响算法的速度。

伪随机数的产生和流密码

随机数产生的原则

  • 伪随机数发生器:用于生产不限长位流的算法称为PRNG。通常应用是做对称流密码的输入
  • 伪随机函数(PRF):PRF用于产生固定长度的伪随机位串。例如对称加密密钥和时变值。
  • 随机性
    • 分布均匀性:0和1出现的频率大约相等。
    • 可伸缩性:用于序列的任何测试也可以用于从序列中抽取的子序列的测试。
    • 独立性:序列中任何子序列不能由其他子序列推导出。
    • 一致性:对于所有初始值(种子),发生器的行为必须具有一致性。基于单个种子产生的输出测试PRNG是不充分的。
  • 不可预测性
    • 前向不可预测性:如果不知道种子,那么不管序列中前面的多少位都无法预测序列中的下一位。
    • 后向不可预测性:从产生的任何值都不能推断出种子值
  • 种子的要求种子本身必须是随机数或者伪随机数。

伪随机数发生器

  • 评价随机数发生器的三个标准
  • 生成函数应是全周期的,即函数再重复之前应该产生0至m-1之间的所有数。
  • 产生的序列应显得很随机。
  • 生成函数可以用32位运算器方便的实现。
线性同余发生器

四个参数:m:模;a:乘数;c:增量; X 0 X_0 :初始值或称种子

随机数序列{X_n}按迭代式: X n + 1 = ( a X n + c ) m o d m X_n+_1=(aX_n+c)mod m

BSS发生器
  • 首先选择两个大素数p和q,要求:
  • 然后BBS按下列算法产生位 B i B_i 序列

    X 0 = s 2 m o d n X_0=s^2modn

    f o r i = 1 t o fori=1to \infty

    X i = ( X i 1 ) 2 m o d n Xi=(X_i-_1)^2modn

    B i = X i m o d 2 Bi=Ximod2

RC4算法

初始化S

开始时,S的元素的值按升序被置为0~255。同时建立一个临时向量T.如果密钥K的长度为256字节,则将K附給T。否则若秘钥长度为keylen个字节(keylen < 256),则将K的值赋给T的前keylen个元素,并循环重复用K的值赋给T剩下的元素,直到T的所有元素都被赋值。

/*初始化*/
for i=0 to 255 do
S[i] = i;
T[i] = K[i mod keylen];

然后用T产生S的初始置换,从S[0]到S[255],对每个S[i],根据由T[i]确定的方案,将S[i]置换为S中的另一字节:

/* S的初始置换 */
j = 0;
for i=0 to 255 do
	j = (j + S[i] + T[i]) mod 256;
Swap(S[i],S[j]);

因为对S的操作仅仅是交换,所以唯一的改变就是置换,S仍然包含所有值为0~255的元素。

密钥流的产生

向量S一旦完成初始化,输入密钥就不再被使用。密钥流的生成过程是,从S[0]到S[255],对每个S[i],根据S的当前配置,将S[i]与S中的另一字节置换。当S[255]置换完成后,操作继续重复从S[0]开始:

/* 密钥流的生成 */	
i,j = 0;
while (true)
	i = (i + 1) mod 256;
	j = (j + S[i]) mod 256;
Swap(S[i],S[j]);
t = (S[i] + S[j]) mod 256;
k = S[t];

加密中,将k的值与明文的下一字节进行异或;解密中,将k的值与密文的下一字节异或。

A5算法

A5流加密法是一种无规律的多LFSR系统。它由三个不同大小的LFSR组成,分别为A、B和C。A有19位,B有22位,C有23位。流输出是这些寄存器的XOR逻辑运算结果。寄存器是无规则调度的,意味着每个寄存器在不同调度规划所移的位不同。每个寄存器的时钟信号由x,y,z的值决定,x是第一个寄存器的第9位,y是第二个寄存器的第11位,z是第三个寄存器的第11位。移位函数实现了三个输入x、y和z的多数功能。当且仅当两个或多个输出为1时,多数函数(maj(x,y,z))为1。因此,只有x XOR maj(x,y,z) = 0时A才移位。只有y XOR maj(x,y,z) = 0时B才移位。只有z XOR maj(x,y,z) = 0时C才移位。

密钥是这三个寄存器的初始值,意味着A5有一个64位的密钥。

真随机数发生器

真随机数发生器(TRNG)使用不可预测源来产生随机数。

  • 熵源
  • 声音/图像输入
  • 磁盘驱动
  • PRNG和TRNG的比较
    • PRNG的效率较高,是确定性的,周期性的
    • TRNG的效率较低,是非确定性的,非周期性的
  • Intel数字随机数发生器(DRNG)
    • 完全由硬件实现
    • 整个DRNG和处理器在同一个多核芯片上,减少了硬件随机数发生器之间的I/O时延。

猜你喜欢

转载自blog.csdn.net/magic_jiayu/article/details/83478185