Blowfish加密算法学习

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
  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用 Blowfish 算法对图像进行加密的 MATLAB 代码: ```matlab % 读入图像 img = imread('lena.png'); % 显示原始图像 figure(1); imshow(img); title('Original Image'); % 将图像转换为一维数组 img = reshape(img, [], 1); % 生成密钥 key = 'my secret key'; % 初始化 Blowfish 加密blowfish = comm.BlowfishEncrypter(key); % 加密图像数据 encrypted = step(blowfish, img); % 将加密后的数据还原为图像 encrypted_img = reshape(encrypted, size(img)); encrypted_img = uint8(encrypted_img); % 显示加密后的图像 figure(2); imshow(encrypted_img); title('Encrypted Image'); % 将加密后的数据解密 decrypted = step(blowfish, encrypted); % 将解密后的数据还原为图像 decrypted_img = reshape(decrypted, size(img)); decrypted_img = uint8(decrypted_img); % 显示解密后的图像 figure(3); imshow(decrypted_img); title('Decrypted Image'); ``` 在这个示例中,我们首先使用 `imread` 函数读入原始图像,然后使用 `reshape` 函数将图像转换为一维数组。接着,我们使用 `comm.BlowfishEncrypter` 类初始化一个 Blowfish 加密器,并使用密钥对图像数据进行加密加密后,我们将加密数据还原为图像格式,并使用 `imshow` 函数显示加密后的图像。 接着,我们使用同样的过程将加密后的数据解密,然后将解密后的数据还原为图像格式,并使用 `imshow` 函数显示解密后的图像。 请注意,这只是一个简单的示例,实际应用中还需要考虑更多的安全因素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sciurdae.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值