【问题标题】:How can I add IV (initialization vector) to AES-256 ECB Encryption to create AES-256 CBC mode?如何将 IV(初始化向量)添加到 AES-256 ECB 加密以创建 AES-256 CBC 模式?
【发布时间】:2018-02-18 18:44:01
【问题描述】:

我有以下代码使用我找到的一个简单的面向字节的 AES-256 库进行 AES-256 ECB 加密 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 所有后续块与前一个块的密文。

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

【问题讨论】:

    标签: c encryption aes cbc-mode ecb


    【解决方案1】:

    逻辑和解释可以在几个地方找到。例如: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 是通过与块上的 IV 进行异或来实现的,ECB 在同一块上并沿着缓冲区中的块移动。

    IV 异或的例子:

    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];
      }
    }
    

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

    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,您可能想研究它并根据您的需要进行调整。希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 2019-03-03
      • 2018-07-08
      • 2013-08-11
      • 2021-06-07
      • 2021-04-22
      • 1970-01-01
      相关资源
      最近更新 更多