我在C中发现了很多AES,Twofish和Serpent的实现。但我真的不明白这些例子。我只知道有些地方提供了反转矩阵的例子。
有人可以指向我的示例或.c文件来加密/解密由char*
和密码代表的数据吗?
答案 0 :(得分:8)
维基百科的文章实际上链接到用C编写的优秀tutorial(由X-N20编写),它引导您完成数学并随时提供C实现,这对于理解该过程非常有用。我还建议您阅读finite field arithmetic。
错过了AES标题的Serpent和Twofish在互联网上没有那么好记录。请记住,每个都提供了参考实现。
实际上自己实施它们需要研究各自的论文,可能还需要参考参考源代码。
请注意,您的200亿条评论都与以下事实有关:为AES指定的接口NIST是每个密码提供128位(16字节)输入块以及128位,192位和256位之一关键块。
为了安全地加密以正确抵制密码分析,您需要一些细心的工作。例如,如果你的最后一个块丢失了几个字节怎么办?你怎么安全地垫?类似地,根据预期用途,还有其他方案,特别是对于大型重复数据,旨在抵制密码分析,您知道加密数据可能包含c:\windows
的内容。评论家试图得到的是,对于任何现实世界的使用,为了保持安全,需要考虑这些事情。
修改由于此主题出现了另一个问题,请点击以下链接:
crypto
下的其余代码。gpg
提供了一整套加密函数。具体来说,如果你是在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语言的参考实现,可以通过互联网轻松找到。