我正在尝试在AES CBC模式下加密和解密,但我有错误。
我的代码:
BYTE initVec[16] = {0x00};
BYTE message[16];
BYTE cipher[16];
for(r = 0; r < 16; r++){
int read2 = fread(cipher, 1, 16, fpIn); // Read last block
aes_decrypt(buffer, cipher, key); // Decrypt - buffer
buffer[r] = buffer[r] ^ cipher[r];
}
在第一个块之后,我需要将前一个密文块与其他块的当前解密数据块进行异或。我怎样才能做到这一点?
答案 0 :(得分:2)
一种方法是使用initVec
的指针。最初,它指向初始向量。然后在每次迭代之后,更改指针以引用上一轮的密文。 CBC基本上意味着每个块的密文用作下一个块的初始向量。第一个块没有前一个块,因此存在一个特殊块: 初始向量。
事实上,看一些代码,这正是我在2001年的时候做的,当时AES是新的,我想make my own:
加密:
void
rijn_cbc_encrypt(rijn_keysched_t *sched, unsigned char *iv, unsigned char *out,
const unsigned char *in, size_t nblocks)
{
unsigned char *ivec = iv;
size_t blocksize = numrows_to_blocksize(sched->rijn_param.rijn_blockrows);
size_t i, nbytes = nblocks * blocksize;
for (i = 0; i < nbytes; i += blocksize) {
xor_mem(out + i, in + i, ivec, blocksize);
rijn_encrypt(sched, out + i, out + i);
ivec = out + i; /* <---- next block's ivec is this block's output! */
}
memcpy(iv, ivec, blocksize);
}
解密。在这里,我们在每次迭代的顶部创建一个ivec
点,指向i > 0
时的前一个输入(密文)块。对于第一次迭代i == 0
,我们将其指向iv
。很简单!
请注意,解密会向后搜索数据!
void
rijn_cbc_decrypt(rijn_keysched_t *sched, unsigned char *iv, unsigned char *out,
const unsigned char *in, size_t nblocks)
{
rijn_block_t iv_save;
size_t blocksize = numrows_to_blocksize(sched->rijn_param.rijn_blockrows);
size_t i, nbytes = nblocks * blocksize;
if (nblocks > 0) {
memcpy(&iv_save, in + nbytes - blocksize, blocksize);
for (i = nbytes - blocksize; i < nbytes; i -= blocksize) {
const unsigned char *ivec = (i > 0) ? in + i - blocksize : iv;
rijn_decrypt(sched, out + i, in + i);
xor_mem(out + i, out + i, ivec, blocksize);
}
memcpy(iv, &iv_save, blocksize);
}
}