C示例中的AES,Serpent或Twofish?

时间:2011-01-14 06:24:53

标签: c encryption aes

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

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

3 个答案:

答案 0 :(得分:8)

维基百科的文章实际上链接到用C编写的优秀tutorial(由X-N20编写),它引导您完成数学并随时提供C实现,这对于理解该过程非常有用。我还建议您阅读finite field arithmetic

错过了AES标题的

SerpentTwofish在互联网上没有那么好记录。请记住,每个都提供了参考实现。

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

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

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

修改由于此主题出现了另一个问题,请点击以下链接:

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

答案 1 :(得分:1)

试图回答killercode尚未回答的问题,这是我尝试实现同样的目标:

  • 下载此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) */
    /* e.g., 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%确定这是否正常使用。

振作! :)

答案 2 :(得分:0)

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