libgcrypt如何递增CTR模式的计数器?

E1a*_*adi 5 cryptography block-cipher libgcrypt ctr-mode

我使用libgcrypt的CTR模式实现使用AES-256加密文件.我希望能够部分解密文件(例如,解密20个块中的5-10个块而不解密整个文件).

我知道通过使用CTR模式,我应该能够做到这一点.我所需要的只是知道正确的计数器.问题在于我所拥有的只是块0的初始计数器.例如,如果我想解密块5,我需要另一个计数器,通过对每个块的初始计数器执行一些操作来实现到5.

我似乎无法找到libgcrypt公开的API,以便为给定初始计数器的后续块计算计数器.

在给定块#0的计数器的情况下,如何计算后续块的计数器(例如块#5)?

Ilm*_*nen 5

如有疑问,请转到。这是 gcrypt 的通用 CTR 模式实现 ( _gcry_cipher_ctr_encrypt()in cipher-ctr.c) 中增加计数器的代码:

for (i = blocksize; i > 0; i--)
  {
    c->u_ctr.ctr[i-1]++;
    if (c->u_ctr.ctr[i-1] != 0)
      break;
  }
Run Code Online (Sandbox Code Playgroud)

在 libgcrypt 源代码的其他地方,还有其他更优化的计数器递增实现,例如在各种特定于密码的快速批量 CTR 加密实现中,但这种通用的恰好很好且可读。(当然,所有这些替代实现无论如何都需要产生相同的计数器值序列,以便 gcrypt 与自身保持兼容。)

好的,那么它实际上是做什么的呢?

好吧,查看上下文(或更具体地说,cipher-internal.h),很明显这c->u_ctr.ctr是一个blocksize无符号字节数组(其中blocksizeAES 等于 16 个字节)。上面的代码将其最后一个字节增加一,并检查结果是否回绕为零。如果没有,它就会停止;如果它确实换行,则代码然后移动到倒数第二个字节,递增它,检查它是否被换行,并继续循环直到它找到一个在递增时不回绕的字节,或者它已经递增所有blocksize字节。

因此,例如,如果您的原始计数器值是{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},那么在递增后它将变为{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}。如果再增加,它会变得{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},那么{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3},依此类推,直到到{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255},在这之后的下一个计数器的值是{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}(,之后{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1}{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2}{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3}等)。

当然,这实际上只是在算术上递增单个 ( blocksize× 8) 位整数,以大端字节序存储在内存中。

  • @E1adi 正如你所看到的,我已经要求迁移到 SO(我是 SO 的一个新模式,仍在学习绳索)。由于您现在拥有 > 15 分,您应该可以投票。但除了投票之外,如果答案解决了您的问题,那么您应该通过点击消息左侧的 V 按钮来接受它。 (2认同)