Blowfish加密算法学习

发布时间:2023年12月28日

Blowfish加密算法

简介

Blowfish是一种对称区块加密算法。该算法流程分为密钥扩展以及数据加密俩部分,每次分组长度64位,密钥采用32-448位,经过扩展后生成多个子密钥数组。进行共16轮的迭代加密。

加密原理

加密流程图:

image-20231228112440897

接收分组长度为64bit的明文,将其分为L和R各32bit。和P进行异或以及F函数加密然后交换迭代16轮,得到密文。

伪代码:

uint32_t P[18];
uint32_t S[4][256];

uint32_t f (uint32_t x) {
   uint32_t h = S[0][x >> 24] + S[1][x >> 16 & 0xff];
   return ( h ^ S[2][x >> 8 & 0xff] ) + S[3][x & 0xff];
}

void encrypt (uint32_t & L, uint32_t & R) {
   for (int i=0 ; i<16 ; i += 2) {
      L ^= P[i];
      R ^= f(L);
      R ^= P[i+1];
      L ^= f(R);
   }
   L ^= P[16];
   R ^= P[17];
   swap (L, R);
}

void decrypt (uint32_t & L, uint32_t & R) {
   for (int i=16 ; i > 0 ; i -= 2) {
      L ^= P[i+1];
      R ^= f(L);
      R ^= P[i];
      L ^= f(R);
   }
   L ^= P[1];
   R ^= P[0];
   swap (L, R);
}

  // ...
  //使用从 pi 派生的值初始化 P 数组和 S 盒; 示例中省略
  // ...
{
   for (int i=0 ; i<18 ; ++i)
      P[i] ^= key[i % keylen];
   uint32_t L = 0, R = 0;
   for (int i=0 ; i<18 ; i+=2) {
      encrypt (L, R);
      P[i] = L; P[i+1] = R;
   }
   for (int i=0 ; i<4 ; ++i)
      for (int j=0 ; j<256; j+=2) {
         encrypt (L, R);
         S[i][j] = L; S[i][j+1] = R;
      }
}

具体加密流程:

密钥扩展

如何生成长度为18的P数组(18个32bit的子密钥)?

最常用的方法就是使用常量π的小数部分,将其转换成为16净值,如下所示:

K1 = 0x76a301d3

K2 = 0xbc452aef

K18 = 0xd7acc4a5

而Blowfish算法的可变密钥长度为32bit到448bit,1到14个32位的数字。使用可变密钥和Pi进行依次异或,也就是伪代码中的:

 for (int i=0 ; i<18 ; ++i)
      P[i] ^= key[i % keylen];

这样就可以的到P数组了。

S-box是一个随机生成的替换盒子,一共有四个,用于F轮函数加密。类似于DES中的S盒将6bit的明文转换成4bit的大小,Blowfish中的S-box作用就是将8bit的数据转换成32bit。S-box的生成也可以和P数组一样使用常量π的小数部分。

之后,取一个全为0的64bits,然后P数组和S-box,应用blowfish算法,生成一个64bits。之后将这个64bits作为输入再次调用blowfish算法,这样最终生成了一个新的P数组:

 uint32_t L = 0, R = 0;
   for (int i=0 ; i<18 ; i+=2) {
      encrypt (L, R);
      P[i] = L; P[i+1] = R;
   }

数据加密

获得了最终的P数组和S-box后,就可以开始数据加密部分了。下面是Blowfish轮函数的处理

Blowfish的轮函数(Feistel)

image-20231228110236324

64bit的明文经过拆分成L和R后,L和P1异或后还是32bit;L异或后的值作为下一轮迭代的R,同时L会进行一次轮函数的加密,32bits会被划分为4个8bit大小的数据,经过S-box被替换成4个32bits大小的数据,之后进行相加和异或的操作,得到的新L会与R进行异或;异或后的值存储在R中,作为下一轮迭代的L。

这样一次迭代就完成了。经过了16次迭代后,P数组中还剩下俩个数据没有被使用。需要单独拿出来进行异或操作。

image-20231228124125441

void encrypt (uint32_t & L, uint32_t & R) {
   for (int i=0 ; i<16 ; i += 2) {
      L ^= P[i];
      R ^= f(L);
      R ^= P[i+1];
      L ^= f(R);
   }
   L ^= P[16];
   R ^= P[17];
   swap (L, R);
}

这样。Blowfish的全部流程就结束了。

python解密脚本

可以使用crypto库进行加解密。

from Crypto.Cipher import Blowfish
key=b'input your key'
bf=Blowfish.new(key,Blowfish.MODE_ECB)
enc=b"input your enc"
print(bf.decrypt(enc))
参考:
https://www.cnblogs.com/flydean/p/14911114.html
https://cloud.tencent.com/developer/article/1836650
文章来源:https://blog.csdn.net/Sciurdae/article/details/135266627
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。