libgcrypt如何为CTR模式增加计数器



我有一个使用libgcrypt的CTR模式实现的AES-256加密的文件。我希望能够对文件进行部分解密(例如,在不解密整个文件的情况下解密20个块中的5-10个块)。

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

在给定初始计数器的情况下,我似乎找不到libgcrypt公开的API来计算后续块的计数器。

给定块#0的计数器,我如何计算后面块(例如块#5)的计数器?

如果有疑问,请转到源代码。以下是gcrypt的通用CTR模式实现中的代码(cipher-ctr.c中的_gcry_cipher_ctr_encrypt()),它递增计数器:

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

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

好吧,那么它到底有什么作用呢?

好吧,看看上下文(或者更具体地说,cipher-internal.h),很明显,c->u_ctr.ctrblocksize无符号字节的数组(其中blocksize等于AES的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)位整数进行算术递增。

相关内容

  • 没有找到相关文章

最新更新