加密算法

1.单向散列算法

2.对称加密算法

1.RC4流密码

  • 算法原理:RC4生成一种称为密钥流的伪随机流,它与明文通过异或操作混合,从而达到加密的效果。解密时与密文进行异或操作。其密钥流由两部分组成,分别是KSR和PRGA。

  • KSA(the Key-Scheduling Algorithm)

    • 初始化256字节的数组S

      • 将S线性填充
      • 用种子密钥对另一表K进行填充
      • 用K表对S表进行初始置换
       for i from 0 to 255:
              S[i] = i
      
          j = 0
      
          for i from 0 to 255:
              j = (j + S[i] + K[i]) mod 256
              swap(S[i], S[j])
  • PRGA

    • 密钥流的生成

      • 从S表中随机获取值组成密钥流与明文异或
      • 伪随机数的生成
      for r=0 to len do
          i=(i+1)%256
          j=(j+S[i])%256
          swap(S[i],S[j])
          t=(S[i]+S[j])%256
          k[r]=S[t]

      注:一旦密钥流生成,种子密钥就失去作用。

      (Python实现见PythonProject/RC4.py)

2.分组加密

1.电码本模式(ECB)

image-20241112150004848

电码本模式的重点在于,使用相同的密钥对进行分组的等长的明文单独加密

  • 优点:每个数据块独立加密,可并行加密,实现简单。

  • 缺点:相同明文会产生相同的密文,不具备数据完整保护性。也就是说,它并不具备混淆和扩散的能力,攻击者可以通过相同的密文块推断明文的一些信息。

  • 适用场景:短消息的加密传输,比如对加密密钥的传输。

2.密文分组链接模式(CBC)

image-20241112151241702

密文分组链接模式的重点在于:

  • 将前一个密文块与当前明文块进行异或运算之后再加密。
  • 初始向量用于第一个块的加密。
  • 加密算法的输入是上一个密文分组和当前明文分组的异或结果

image-20241112151738547

优缺点及适用场景:

  • 优点:每个密文块的加密依赖前一个密文块,具备数据完整保护性。
  • 缺点:传输过程中的错误会传播下去,不适合并行处理。
  • 适用场景:适用于常规文件加密,非实时加密等场景。

3.密文反馈模式(CFB)

image-20241112152305771

密文反馈模式的重点在于:

  • 前一个密文块作为加密算法的输入

  • 加密算法生成一个密钥流,再与当前的明文块进行异或得到密文块。

  • 明文本身并不在加密算法中。

优缺点及适用场景:

  • 优点:可以处理任意长度的数据,实时加密解密,可以部分解密数据。
  • 缺点:错误传播的敏感性,不适合并行处理,需要保证初始向量的唯一性和完整性。

4.输出反馈模式(OFB)

image-20241112155548523

输出反馈模式的重点在于:

  • 前一个加密算法的输出作为下一个加密算法的输入

  • 加密后得到密钥流

  • 密钥流与明文进行异或得到密文块

image-20241112155958301

CFB和OFB模式的唯一不同在于密钥流的获取方式不同。

优缺点及适用场景:

  • 优点:长度可变,实时加密,错误传播敏感。

  • 缺点:传输错误不可恢复 ,无法提供数据完整性保护,不支持并行加密。

  • 适用场景:实时数据流加密和随机访问的场景。

5.计数器模式(CTR)

image-20241112212818757

计数器模式重点在于:

  • 每一个明文分组都与一个经过加密计数器异或
  • 对于后续的分组,计数器自增
  • 加密算法针对的是计数器

优缺点及适用场景:

优点:

  • 可以并行处理
  • 随机访问,根据计数器的值和密钥生成密钥流
  • 不受错误传播的影响

缺点:

  • 计数器必须唯一
  • 密钥流和明文的相关性较弱

适用场景:

  • 并行加密
  • 随机访问
  • 实时加密

image-20241112213505563


3.TEA系列加密算法

4.DES加密算法

​ DES是一个经典的分组加密算法,通常一组是64位的数据,以电码本模式加密以下是加密步骤:

  1. 密钥生成:首先,从用户提供的64位密钥中提取出56位有效密钥(每第8位用于奇偶校验),然后生成16个子密钥,供每轮加密使用。
  2. 初始置换(IP):对64位输入数据进行初始置换,重排列数据的位。
  3. 16轮加密:进行16轮的 Feistel 结构加密。在每一轮中,数据被分为左右两个32位部分,右半部分经过扩展置换和与当前轮的子密钥进行异或运算,经过S-盒替换后,再经过P-盒置换,最后与左半部分进行异或运算,交换左右部分。
  4. 逆初始置换(IP⁻¹):在完成16轮加密后,对数据进行逆初始置换,得到最终的密文

1.密钥生成

​ 种子密钥为64位且唯一,经过两轮置换选择变为48位:

image-20241115191827253

  • PC1置换:

    PC1置换将8位校验位去除,并进行比特重排打乱顺序

    image-20241115191945874

  • 将PC1置换后的56位中间密钥分为C,D两部分,经过16次迭代,每次迭代进行不同次数的循环左移,得到打乱顺序后的56位中间密钥,值得注意的是,每一次迭代都是在前一次产生的Ci,Di的基础上进行循环左移,生成Ci+1,Di+1且这里的每一次迭代都生成一个中间密钥M-keyi,只有这样才能保证能输出16个不同子密钥。

    image-20241115192505906

  • PC2置换:

​ 使用PC2置换将56位中间密钥M-keyi去除8位并打乱

image-20241115192621065

  • 得到48位密钥keyi

2.初始置换

​ 使用IP(Initial Permutation)置换对明文进行比特重排。

image-20241115193345521

3.16轮迭代加密

​ 进行16轮的 Feistel 结构加密。

Feistel结构加密

​ Feistel结构加密是指在每一轮中,数据被分为左右两个32位部分Ai,Bi,左半部分变不变,右半部分经过E扩展置换和与当前轮的子密钥进行异或运算,经过S-盒替换后,再经过P-盒置换,最后与左半部分进行异或运算,交换左右部分。

image-20241115195530995
1.E扩展置换

​ E扩展置换将32位的Bi置换为48位的数据。而将32位扩展至48位关键在于将32位均分为8组,每一组的4位数据如何扩展至6位。

​ E扩展将原4位数据前后各加一位以此达到扩展的目的,前一位来自于前一组的最后一位,后一位来自后一组的第一位。第一组的前一位来自最后一组的最后一位,最后一组的后一位来自第一组的第一位。最终得到EBi以下是一个示例:

image-20241115195942892
2.与子密钥异或

​ EBi^keyi

3.S-盒压缩

​ S-盒压缩将EBi均分为8组,将头尾数据分别转化为10进制数,以头尾十进制作行数,中间十进制数作列数,在S-盒表中查找对应数据,得到的十进制数转化为2进制就得到压缩后的4位数据,拼接起来得到32位数据SEBi

image-20241115201231380

4.P-盒替换

​ 将SEBi进行P-盒置换得到PSEBi

image-20241115201544932

5.与Ai进行异或

​ 将PSEBi与Ai进行异或,赋值给Ai+1,将Ai赋值给Bi+1

4.逆初始置换(IP⁻¹)

image-20241115202459825

3.公开密钥加密算法

4.其他算法

2.Base64编码

​ Base64编码将二进制数据编码为可显示的字母和数字,用于传送图形,声音和传真等非文本数据,常用于MIME电子邮件格式中。其使用含有65个字符的ASCII字符集,并用6个进制位表示一个可显示字符。

image-20241107183531620

  • Base64编过程:

    • 以3个字节为一组,将第一个字节放在24位缓冲区的高8位,第二个放在中8位,第三个放在低8位。

    • 对24位缓冲区以6位为索引,高位优先,从字符串“ABCDEFGHIJKLMN OPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”中取出相应元素作为输出

    • 如果仅有一字节或两字节输入,那么只使用输出的2~3个字节,其余用”=“填充

    • “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”即为字符集

      image-20241107184614133

(关于Base64的解码程序,详见PythonProject1/Base64.py)

3.Hex编码

​ Hex编码将数据以16进制数表示。

​ 编码方式:每个字节(8位)的数据被转换为两个Hex字符。第一个字符代表字节的高4位,第二个字符代表字节的低4位。

​ 字符集:“0123456789abcdef”

​ (关于Hex编码的解码程序,详见Python/Hex.py)