C示例中的AES,Serpent或Twofish?

我在C中发现了很多AES,Twofish和Serpent的实现。但我真的不明白这些例子。 我只知道有些地方提供了反转矩阵的例子。

有人可以指向我的示例或.c文件来加密/解密由char*和密码表示的数据吗?

维基百科的文章实际上链接到一个用C编写的优秀教程 (由X-N20编写),它引导您完成数学并在旅途中提供C实现,这对于理解该过程非常有用。 我还建议阅读有限域算法 。

错过了AES标题的Serpent和Twofish在互联网上并没有那么好记录。 请记住,每个都提供参考实现。

实际上自己实施它们需要研究各自的论文,可能还需要参考参考源代码。

请注意,您的200亿条评论都与以下事实有关:为AES指定的接口NIST是每个密码提供128位(16字节)输入块以及128位,192位和256位密钥块之一。

为了安全地加密以适当地抵制密码分析,您需要一些谨慎的工作。 例如,如果你的最后一个块丢失了几个字节怎么办? 你怎么安全地垫? 类似地,根据预期用途,还有其他方案,特别是对于大型重复数据,旨在抵制密码分析,其中您知道加密数据可能包含c:\windows的内容。 评论家试图得到的是,对于任何现实世界的使用,为了保持安全,这些事情需要考虑。

编辑由于此主题出现了另一个问题,这里有一些链接:

  • Brian Gladman的各种加密算法的ASM / C代码 ,包括AES,SHA和Serpent。
  • OpenSSL的 CVS中的AES代码 。 另见DES 。 他们没有实施Serpent。 您可能还想在crypto下查看其余代码。
  • 加密++ 。 如果您可以使用C ++并且只是加密的最终用户,那么您需要此库(tm)。 那里有我从未听说过的算法。 他们的SVN主干 。
  • libgcrypt为gpg提供了一整套加密函数。 具体来说,如果你是在AES之后,你可能在这里找不到它,但你会发现山茶花和蛇。

试图回答 – 仍然没有答案 – 杀手码的问题,这是我尝试实现同样的事情:

  • 下载这个TwoFish代码(感谢Schneier等人): https ://www.schneier.com/code/twofish-reference-c.zip

  • 使用此代码(当然风险自负):

     int mode = MODE_CBC; int keySize = 256; int result = 0; keyInstance ki; /* key information, including tables */ cipherInstance ci; /* keeps mode (ECB, CBC) and IV */ BYTE plainText[MAX_BLK_CNT*(BLOCK_SIZE / 8)]; // 64 in size! BYTE cipherText[MAX_BLK_CNT*(BLOCK_SIZE / 8)]; BYTE decryptOut[MAX_BLK_CNT*(BLOCK_SIZE / 8)]; BYTE iv[BLOCK_SIZE / 8]; int i; /* select number of bytes to encrypt (multiple of block) */ /* eg, byteCnt = 16, 32, 48, 64 */ //byteCnt = (BLOCK_SIZE / 8) * (1 + (rand() % MAX_BLK_CNT)); /* generate test data */; int plainTextLength = 65; for (i = 0; i < min(plainTextLength, MAX_BLK_CNT*(BLOCK_SIZE / 8)); i++) plainText[i] = (BYTE)rand(); if (plainTextLength > MAX_BLK_CNT * BLOCK_SIZE / 8) { ::MessageBox(NULL, _T("You need to increase your MAX_BLK_CNT for the plain-text to fit in one call."), _T("Error"), MB_OK); return; } int byteCnt = ceil((double)plainTextLength / (BLOCK_SIZE / 8.0)) * (BLOCK_SIZE / 8); /* ----------------------- */ /* 'dummy' setup for a 128-bit key */ if (makeKey(&ki, DIR_ENCRYPT, keySize, NULL) != TRUE) result = 1; /* ----------------------- */ /* 'dummy' setup for cipher */ if (cipherInit(&ci, mode, NULL) != TRUE) result = 1; /* select key bits */ for (i = 0; i < keySize / 32; i++) ki.key32[i] = 0x10003 * rand(); /* run the key schedule */ reKey(&ki); /* set up random iv (if needed)*/ if (mode != MODE_ECB) { for (i = 0; i < sizeof(iv); i++) iv[i] = (BYTE)rand(); /* copy the IV to ci */ memcpy(ci.iv32, iv, sizeof(ci.iv32)); } /* encrypt the bytes */ if (blockEncrypt(&ci, &ki, plainText, byteCnt * 8, cipherText) != byteCnt * 8) result = 1; /* ----------------------- */ /* decrypt the bytes */ if (mode != MODE_ECB) /* first re-init the IV (if needed) */ memcpy(ci.iv32, iv, sizeof(ci.iv32)); if (blockDecrypt(&ci, &ki, cipherText, byteCnt * 8, decryptOut) != byteCnt * 8) result = 1; /* make sure the decrypt output matches original plaintext */ if (memcmp(plainText, decryptOut, byteCnt)) result = 1; if (result == 0) ::MessageBox(NULL, _T("Success"), _T("SUCCESS"), MB_OK); 

这是我的尝试,似乎工作得很好。

它正在使用CBC模式。

如果有人有任何建议,我愿意接受建议。

当然,您可能希望将MAX_BLK_CNT变量并相应地增加它,以便能够加密各种数据长度。 虽然我不是100%确定这是否正常使用。

欢呼! 🙂

下载OpenSSL / Putty / GnuPG源代码。 它们都包含相应加密算法的来源。 此外,每个算法都有C语言的参考实现,可以通过Internet轻松找到。