J’ai trouvé de nombreuses implémentations d’AES, Twofish et Serpent en C. Mais je ne comprends pas vraiment les exemples. Je comprends seulement que certains ont été fournis avec des exemples pour inverser une masortingce.
Quelqu’un peut-il m’indiquer un exemple ou un fichier .c pour chiffrer / déchiffrer des données représentées par un caractère char*
et un mot de passe?
L’article de Wikipédia est en fait lié à un excellent tutoriel (rédigé par X-N20 ) écrit en C qui vous guide dans les mathématiques et fournit des implémentations de C à la volée, ce qui est très utile pour comprendre le processus. Je recommanderais également de lire l’ arithmétique en champ fini .
Serpent et Twofish , ayant raté le titre AES, ne sont pas aussi bien documentés sur Internet. Rappelez-vous cependant que chacun fournit des implémentations de référence.
En réalité, leur mise en œuvre par vous-même nécessitera une étude de leurs papiers respectifs et probablement du code source de référence.
Notez que vos 20 milliards de commentaires concernent tous le fait que l’interface NIST spécifiée pour AES était que chaque chiffrement fournissait un bloc d’entrée de 128 bits (16 octets) et l’un des blocs de clés de 128 bits, 192 bits et 256 bits.
Afin de chiffrer de manière sécurisée de manière à résister correctement à l’parsing cryptée, un travail minutieux est nécessaire. Par exemple, que se passe-t-il si votre dernier bloc manque de quelques octets? Comment tamponnez-vous en toute sécurité? De même, en fonction de l’utilisation prévue, il existe d’autres schémas, en particulier pour les données répétitives volumineuses, conçus pour résister à la cryptparsing lorsque vous savez que les données cryptées contiennent probablement le contenu de c:\windows
. Ce que les commentateurs essaient de comprendre, c’est que, pour toute utilisation dans le monde réel, pour restr en sécurité, ces éléments doivent être pris en compte.
Modifier Puisqu’une autre question a surgi sur ce sujet, voici quelques liens:
crypto
. gpg
. Spécifiquement, si vous êtes après AES, vous ne le trouverez peut-être pas ici, mais vous trouverez du camélia et du serpent. En essayant de répondre à la question du code de la mort qui rest encore sans réponse, voici ce que je tente de faire:
Téléchargez ce code TwoFish (merci à Schneier et autres): https://www.schneier.com/code/twofish-reference-c.zip
Utilisez ce code (à vos risques et périls bien sûr):
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);
C'était ma tentative et cela semble fonctionner assez bien.
Il utilise le mode CBC.
Je suis ouvert aux suggestions, si quelqu'un en a.
Bien sûr, vous voudrez peut-être faire de MAX_BLK_CNT
une variable et l’augmenter en conséquence, pour pouvoir chiffrer diverses longueurs de données. Bien que je ne sois pas sûr à 100% si telle est son utilisation normale.
Acclamation! 🙂
Téléchargez les sources OpenSSL / Putty / GnuPG. Tous contiennent la source de l’algorithme de chiffrement correspondant. En outre, chaque algorithme a une implémentation de référence en C, qui peut être facilement trouvée sur Internet.