1

我有以下代码使用我在这里找到的简单的面向字节的 AES-256 库进行 AES-256 ECB 加密。

主要的:

#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. 将所有后续块与前一个块的密文进行异或。

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

4

1 回答 1

0

逻辑和解释可以在几个地方找到。例如:ECB vs CBCBlock 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];
  }
}

使用 IV 和 ECB 的 XOR 的 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,您可能想研究它并根据您的需要调整它。我希望它有所帮助。

于 2018-02-18T19:55:35.390 回答