如何将 IV(初始化向量)添加到 AES-256 ECB 加密以创建 AES-256 CBC 模式?

How can I add IV (initialization vector) to AES-256 ECB Encryption to create AES-256 CBC mode?

我有以下代码用于 AES-256 ECB 加密,使用我发现的一个简单的面向字节的 AES-256 库 here

主要:

#define DUMP(s, i, buf, sz)  {printf(s); \
for (i = 0; i < (sz);i++) \
printf("%02x ", buf[i]); \
printf("\n");}

int main (int argc, char *argv[])
{
aes256_context ctx; 
uint8_t key[32] = "39P8TXDMBCYF4C1NI1CDFJ1WL6P5TTKZ";
uint8_t buf[16] = "KUC7EWG6M2D1WW8F";
uint8_t i;

DUMP("txt: ", i, buf, sizeof(buf));
DUMP("key: ", i, key, sizeof(key));
printf("---\n");

aes256_init(&ctx, key);
aes256_encrypt_ecb(&ctx, buf);

DUMP("enc: ", i, buf, sizeof(buf));

aes256_init(&ctx, key);
aes256_decrypt_ecb(&ctx, buf);
DUMP("dec: ", i, buf, sizeof(buf));

aes256_done(&ctx);
return 0;
}

加密函数:

void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf)
{
uint8_t i, rcon;
aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
for(i = 1, rcon = 1; i < 14; ++i)
{
aes_subBytes(buf);
aes_shiftRows(buf);
aes_mixColumns(buf);
if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]);
else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
}
aes_subBytes(buf);
aes_shiftRows(buf);
aes_expandEncKey(ctx->key, &rcon);
aes_addRoundKey(buf, ctx->key);
} /* aes256_encrypt */

我想在此程序中添加一个 IV 以创建 AES-256 CBC 模式。据我了解,IV实现如下:

  1. 第一个块与 IV 异或。
  2. XOR 所有后续块与前一个块的密文。

我的问题是逻辑是什么样的?我如何在我的代码中实现它?

可以在几个地方找到逻辑和解释。例如:ECB vs CBC or Block cipher mode of operation.

CBC = 密码块链接是一种将块连接在一起的方法。

所做的不是单独处理每个块,而是将每个块与加密的前一个块进行异或运算。这实际上意味着每个块都取决于前一个块的输出。

每个块都与前一个块的密文进行异或,正如引用文章中的图表所解释的那样。

实际上,一旦一个块被 ECB 加密:

 Cipher((state_t*)buf, ctx->RoundKey);

void AES_ECB_encrypt(struct AES_ctx *ctx,const uint8_t* buf)
{
  // The next function call encrypts the PlainText with the Key using AES algorithm.
  Cipher((state_t*)buf, ctx->RoundKey);
}

CBC 是通过 XOR 与块上的 IV 和同一块上的 ECB 并沿着缓冲区中的块移动来实现的。

与 IV 的 XOR 示例:

static void XorWithIv(uint8_t* buf, uint8_t* Iv)
{
  uint8_t i;
  for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
  {
    buf[i] ^= Iv[i];
  }
}

使用 XOR 与 IV 和 ECB 的 CBC 示例:

void AES_CBC_encrypt_buffer(struct AES_ctx *ctx,uint8_t* buf, uint32_t length)
{
  uintptr_t i;
  uint8_t *Iv = ctx->Iv;
  for (i = 0; i < length; i += AES_BLOCKLEN)
  {
    XorWithIv(buf, Iv);
    Cipher((state_t*)buf, ctx->RoundKey);
    Iv = buf;
    buf += AES_BLOCKLEN;
    //printf("Step %d - %d", i/16, i);
  }
  /* store Iv in ctx for next call */
  memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
}

以上实现来自tiny-AES,您可能想研究它并根据您的需要进行调整。希望对你有帮助。