科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网网络频道Twofish加密算法详解(上)

Twofish加密算法详解(上)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

这几天分析一软件,发现其序列号用到了Twofish 加密算法,上网找了很久 都没有找到相应的中文资料,于是决定等我研究明白之后写一篇文档,以便 给今后需要使用Twofish 的人以参考,下面进入正题。

作者:论坛整理 来源:zdnet网络安全 2007年12月25日

关键字: 安全技术 加密 Twofish

  • 评论
  • 分享微博
  • 分享邮件
这几天分析一软件,发现其序列号用到了Twofish 加密算法,上网找了很久
         都没有找到相应的中文资料,于是决定等我研究明白之后写一篇文档,以便
         给今后需要使用Twofish 的人以参考,下面进入正题。

             首先介绍一下Twofish 的历史,如果您只想了解如何运用此算法,请直
         接跳到下一段。在1972到1974年中,National Bureau of Standards (现在
         更名为National Institute of Standards and Tecnology,缩写为NIST)首
         次公开征求一种标准的数据加密算法,结果产生了 DES ( Data Encryption
         Standard) 加密算法。但DES 的密钥长度对于现在计算机的运行速度来说,
         在某些高机密的场合显得有点不足,已经不再安全。所以1999年NIST决定采
         用一种更高标准的加密算法AES (Advanced Encryption Standard)来代替原
         来的DES。首先这种加密算法必须是块加密 (block cipher),因为块加密可
         以被用来对数据流进行加密,也可以被用来制造一些专用的数据加密设备。
         其次,这种加密算法必须使用更长的密钥,更大的加密块,更高的加密速度,
         更高的灵活性。Twofish 则是counterpane 公司向NIST提交的一种满足AES
         要求的加密算法。Twofish 采用128位数据块(128 bits block),128- 192-
         256-bit 可变长度密钥。Twofish 算法是进入NIST第二轮 5种加密算法中的
         一种。下面分步详细讲解如何使用Twofish 加密算法。

             现在网上能找到的大部分Twofish 的源程序都是外国人写的,还可以找
         到有一些 Twofish SDK。但它们普遍代码庞大,使用起来都不太方便,不如
         根据自己的需要,自己写一个代码。我写了一个可以用Twofish 进行加密解
         密的代码,才不过 400行,所以在看下面的文章之前,你首先要对自己有信
         心,因为其中用到了一些数学知识。你也可以参考Twofish 的官方文档:

         http://www.counterpane.com/twofish.html

         其中 paper-twofish-paper.pdf 有 68页,全英文,还不如看我这篇文章来
         的快,呵呵,不过你可以把它与本文互相参照着看。

             Twofish 加密算法的流程图如下:

         ┌───────────────────────────────┐
         │                          P (128 bits)                        │
         └┬───┬─────────────────────┬───┬┘
           │      │                                          │      │
           ⊙←K0  ⊙←K1      <- input whitening ->       K2→⊙  K3→⊙
           │      │                                          │      │
           │      │┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐  │      │
           │      │┆F                                   ┆  │      │
           │      │┆┌┄┄┄┄┄┄┄┄┄┐              ┆  │   <<1│
           │      │┆┆g                 ┆       K(2r+8)┆  │      │
           │      │┆┆            ┌─┐┆            │┆  │      │
           │      │┆┆  ┌S-box0->│  │┆┌┄┄┄┐  │┆  │      │
           │      │┆┆  ├S-box1->│M │┆┆  PHT ┆  ↓┆  ↓      │
           ├───┼┼┼→│        │D ├┼┼→⊙┬┼→⊙┼→⊙      │
           │      │┆┆  ├S-box2->│S │┆┆  ↑│┆    ┆  │      │
           │      │┆┆  └S-box3->│  │┆┆  ││┆    ┆  │      │
           │      │┆┆            └─┘┆┆  ││┆    ┆  │      │
           │      │┆└┄┄┄┄┄┄┄┄┄┘┆  ││┆    ┆  │      │
           │      │┆┌┄┄┄┄┄┄┄┄┄┐┆  ││┆    ┆  │      │
           │      │┆┆g                 ┆┆  ││┆    ┆  │      │
           │      │┆┆            ┌─┐┆┆  ││┆    ┆  │      │
           │      │┆┆  ┌S-box0->│  │┆┆  ││┆    ┆  │      │
           │      │┆┆  ├S-box1->│M │┆┆  ││┆    ┆  │      ↓
           │   <<8├┼┼→│        │D ├┼┼─┴⊙┼→⊙┼─┼──→⊙
           │      │┆┆  ├S-box2->│S │┆┆      ┆  ↑┆  │      │
           │      │┆┆  └S-box3->│  │┆└┄┄┄┘  │┆  │      │
           │      │┆┆            └─┘┆            │┆  │      │
           │      │┆└┄┄┄┄┄┄┄┄┄┘       K(2r+9)┆  │      │
           │      │└┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘  │>>1   │
           │      │                                          │      │
           │      └─────────┐    ┌────────┘      │
           │                           ╲  ╱                         │
           └─────────────┐ ╳ ┌────────────┘
                                        ╳  ╳
           ┌─────────────┘ ╳ └────────────┐
           │      ┌──────────┘└─────────┐      │

           ...     ...              15 more rounds             ...     ...

           │      └─────────┐    ┌────────┘      │
           │                           ╲  ╱                         │
           └─────────────┐ ╳ ┌────────────┘
                                        ╳  ╳
           ┌─────────────┘ ╳ └────────────┐
           │      ┌──────────┘└─────────┐      │
           ↓      ↓                                          ↓      ↓
           ⊙←K4  ⊙←K5      <- output whitening ->      K6→⊙  →K7⊙
           ↓      ↓                                          ↓      ↓
         ┌───────────────────────────────┐
         │                          C (128 bits)                        │
         └───────────────────────────────┘

             怎么样?看完之后有点晕了吧?里面有很多英文的术语,我不知道对应
         的中文怎么说,所以索性下面的术语就直接都用英文的好了。在讲解每一步
         具体如何计算之前我们先做一些准备工作,说明一下其中字母各代表什么。
         其中开始处 P(plain text)表示需要进行加密的 128-bit数据,也即16字节。
         然后将这16字节分为 4组,每组32-bit,即 4字节。在循环之前首先对这 4
         组数据分别用K0 K1 K2 K3进行异或操作,称之为input whitening,然后对
         异或后的数据分组进行计算。计算后将 1-3 2-4组的数据对换,如此循环15
         次,再 1-3 2-4对换一次。对这 4组数据分别用 K4 K5 K6 K7异或操作,称
         之为 output whitening。最后将这 4组数据组合成 16字节的数据,也就是
         最后的密文 C(cipher text),长度跟加密前的 P同样是128-bit。下面详细
         说明每一计算步骤。

         1.计算前的准备工作

             加密前的plain text是128 bits,也就是16 bytes。假设这16 bytes分
         别是p0, ... ,p15。用little-endian conversion (如果你不明白,可以参
         看我的blog中的的一篇相关文章),将p0, ... ,p15分为 4组:

             P(i) = ∑p(4i+j)2^(8j),其中i,j = 0, ... ,3

         2.Input whitening

             R(0,i) = P(i) xor K(i),其中i = 0, ... ,3

             这里的K(i)是跟据密钥算出来的32-bit数据,计算方法后面介绍。
         3.16次循环

             在16次循环的每一次中, 4组数据的前两组与当前循环次数通过 F进行
         计算,计算出 2组数据。第 3组数据与计算出的第 1组数据异或,然后向右
         循环移动一位。第 4组数据向左循环移动一位,然后异或计算出的第 2组数
         据。然后将 1-3 2-4组数据对换,作为下一轮计算的数据。程序表示如下:

             (F(r,0), F(r,1)) = F(R(r,0), R(r,1), r)
                     R(r+1,0) = ROR(R(r,2) xor F(r,0), 1)
                     R(r+1,1) = ROL(R(r,3), 1) xor F(r,1)
                     R(r+1,2) = R(r,0)
                     R(r+1,3) = R(r,1)

         4.Output whitening

             C(i) = R(16,(i+2) mod 4) xor K(i+4),其中i = 0, ... ,3

             这里的K(i+4)同样是根据密钥计算出来的32-bit数据,目前为止总共有

             K(i) i = 0, ... ,7

         5.计算后组成密文

             c(i) = [C(i/4) / 2^(8(i mod 4))] mod 2^8,其中i = 0, ... ,15

             这样,128-bit的C就计算出来了。
         前面的K(i)和函数 F还没有说明,下面先介绍函数 F。

         1. The Function F

             (F0, F1) = F(R0, R1, r)

             其中参数R0, R1是32-bit 数据,r表示当前循环的次数,T0,T1是计算
         出的结果,同样都是32-bit 的数据。

             T0 = g(R0)
             T1 = g(ROL(R1, 8))
             F0 = (T0 +  T1 + K(2r+8)) mod 2^32
             F1 = (T0 + 2T1 + K(2r+9)) mod 2^32

         其中后两步计算被称为 PHT(Pseudo-Hadamard Transforms)。
         这里K(i) i = 8, ... 39,加上前面的i = 0, ... ,7,所以总共有40个K

             K(i) i = 0, ... ,39

         我们仍然先不讲如何计算K,而先介绍函数 g。

         2. The Function g

             Z = g(X)

             函数 g是Twofish 算法的核心,也是比较难理解的一部分。其中参数 X
         与计算结果 Z都是32-bit的数据。

             x(i) = [X/2^(8i)] mod 2^8,其中i = 0, ... ,3
             y(i) = s(i)(x(i))        ,其中i = 0, ... ,3
             ┌  ┐  ┌   ┐  ┌  ┐
             │z0│  │   │  │y0│
             │z1│= │MDS│·│y1│
             │z2│  │   │  │y2│
             │z3│  │   │  │y3│
             └  ┘  └   ┘  └  ┘
             Z = ∑z(i)2^(8i),其中i = 0, ... ,3

             首先将32-bit的参数 X分为 4个字节x0, ... ,x4,然后每一个x(i) 分
         别进入自己的S-box,其中每一个S-box 都是8-bit输入, 8-bit输出。这样
         计算出来的 y(i)仍然是 8-bit,组成一个4 * 1的列向量,这个向量与定义
         在GF(2^8)上的4*4 MDS矩阵相乘,得到 4*1的列向量。最后将这个列向量中
         的四个元素组成32-bit数据 Z。其中 MDS矩阵为:

                   ┌           ┐
                   │01 EF 5B 5B│
             MDS = │5B EF EF 01│
                   │EF 5B 01 EF│
                   │EF 01 EF 5B│
                   └           ┘

         为了数据的计算,还必须明确定义GF,对于MDS 矩阵,GF的定义如下:

             GF(2^8) ≡ GF(2)(x)/v(x),其中v(x) = x^8 + x^6 + x^5 + x^3 + 1

         又不太明白了吧?上面不太容易理解的地方有两处,一个是 S-boxes,一个
         是在有限域GF上如何进行计算。对于前一个问题,我们将会在下面进行介绍,
         对于后一个问题,我将会专门写一篇在有限域上进行计算的文章,如果你感
         兴趣可以去我的blog。

             我们再总结一下吧,目前还有哪些问题没有解决:

             K(i),i = 0, ... ,39

             s(i)(),i = 0, ... ,3

         以上这两组数据都是通过密钥计算出来的 (key-dependent),所以下面我们
         该介绍一下密钥了。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章