Bonjour à tous,
j'ai un problème avec un code sensé calculer le hash MD5 d'une chaîne de caractères que j'ai trouvé sur Internet.
J'ai trouvé sur un autre site l'implémentation d'un algo pour calculer le hash MD5 d'une chaîne de caractères. Le code comportait des erreurs, et l'utilisateurs suivant l'a aidé à le corriger. Mais en appliquant les corrections, le code ne fonctionne pas chez moi ! Voilà le code, avec mes corrections (j'ai parfois mis des commentaires sur ce que j'ai corrigé) :
main.c
md5.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <stdio.h> #include <stdlib.h> #include "md5.h" int main(void) { char buffer[33]; md5Digest("tototiti", 8, buffer); printf("MD5:%s\n", buffer); system("pause"); return 0; }
md5.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include "md5var.h" #include "md5.h" //Apparemment, pour faire fonctionner htonl() #include <winsock.h> #ifdef _MSC_VER #pragma comment(lib, "ws2_32.lib") #endif void md5Init() { int i; for(i = 0; i < 64; i++) y[i] = llabs((unsigned long long)(sin(i + 1.0) * powl(2.0, 32.0))); initialised = 1; } int md5Digest(char* src, unsigned long long size, char* dst) // Size is expressed in bits { unsigned char* paddedBuffer = NULL; unsigned long long paddedBufferSize = 0; unsigned long long paddingSize = 0; unsigned char* MD5 = (unsigned char*)dst; unsigned int tmpBuffer[16]; unsigned int i = 0, j = 0; unsigned int A = 0, B = 0, C = 0, D = 0, t = 0, H1 = 0, H2 = 0, H3 = 0, H4 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0, m = 0; //Initialisation décalée après la déclaration des variables if(!initialised) { md5Init(); } // Padding paddedBufferSize = ((size % 512) < 448) ? (size + 448 - (size % 512)) : (size + 960 - (size % 512)); //Cast pour éviter l'erreur [Impossible d'assigner une valeur de type "void *" à une entité de type "unsigned char *] paddedBuffer = (unsigned char *)malloc((paddedBufferSize + 64) >> 3); memcpy(paddedBuffer, src, ((size % 8) ? (size >> 3) : (size >> 3) + 1)); paddedBuffer[(size >> 3)] &= (0xFF << (8 - (size % 8))); paddedBuffer[(size >> 3)] |= (0x80 >> (size % 8)); for(i = (size >> 3) + 1; i < (paddedBufferSize + 64) / 8; i++) paddedBuffer[i] = 0; paddedBuffer[(paddedBufferSize >> 3)] = size & 0x00000000000000FFULL; paddedBuffer[(paddedBufferSize >> 3) + 1] = (size & 0x000000000000FF00ULL) >> 8; paddedBuffer[(paddedBufferSize >> 3) + 2] = (size & 0x0000000000FF0000ULL) >> 16; paddedBuffer[(paddedBufferSize >> 3) + 3] = (size & 0x00000000FF000000ULL) >> 24; paddedBuffer[(paddedBufferSize >> 3) + 4] = (size & 0x000000FF00000000ULL) >> 32; paddedBuffer[(paddedBufferSize >> 3) + 5] = (size & 0x0000FF0000000000ULL) >> 40; paddedBuffer[(paddedBufferSize >> 3) + 6] = (size & 0x00FF000000000000ULL) >> 48; paddedBuffer[(paddedBufferSize >> 3) + 7] = (size & 0xFF00000000000000ULL) >> 56; // Initialisation h1 = 0x67452301; h2 = 0xefcdab89; h3 = 0x98badcfe; h4 = 0x10325476; H1 = h1; H2 = h2; H3 = h3; H4 = h4; A = h1; B = h2; C = h3; D = h4; m = (paddedBufferSize + 64) >> 9; // MD5 Calculation for(i = 0; i < m; i++) { for(j = 0; j < 16; j++) { tmpBuffer[j] = ((unsigned int*)paddedBuffer)[16 * i + j]; } for(j = 0; j < 16; j++) { t = (A + F(B, C, D) + tmpBuffer[z[j]] + y[j]); A = D; t = B + ROTL(t, s[j]); D = C; C = B; B = t; } for(j = 16; j < 32; j++) { t = (A + G(B, C, D) + tmpBuffer[z[j]] + y[j]); A = D; t = B + ROTL(t, s[j]); D = C; C = B; B = t; } for(j = 32; j < 48; j++) { t = (A + H(B, C, D) + tmpBuffer[z[j]] + y[j]); A = D; t = B + ROTL(t, s[j]); D = C; C = B; B = t; } for(j = 48; j < 64; j++) { t = (A + I(B, C, D) + tmpBuffer[z[j]] + y[j]); A = D; t = B + ROTL(t, s[j]); D = C; C = B; B = t; } H1 += A; H2 += B; H3 += C; H4 += D; } sprintf(dst, "%08x%08x%08x%08x\0", htonl(H1), htonl(H2), htonl(H3), htonl(H4)); free(paddedBuffer); return 0; }
md5var.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 #ifndef MD5_H #define MD5_H void md5Init(); int md5Digest(char* src, unsigned long long size, char* dst); #endif
Problème actuel : le hash MD5 est bien généré, sauf que... ce n'est pas le bon ! Par exemple, lorsque je tape un mot de passe comme "toto1234", il ne trouve pas le même hash qu'un site comme md5.fr. Par contre, pas de problème pour une chaîne vide, le bon hash est généré. De plus, les hash de "toto" et "titi" sont identiques.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #ifndef MD5VAR_H #define MD5VAR_H #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) #define ROTL(number, shift) ((number << shift) | (number >> (32 - shift))) #define ROTR(number, shift) ((number >> shift) | (number << (32 - shift))) unsigned long long s[64] = {7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22, 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23, 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21}; unsigned long long y[64]; unsigned long long z[64] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9}; int initialised = 0; #endif
Merci à tous pour votre aide, j'aimerais vraiment comprendre ce qui ne va pas
PS : pour ceux qui me conseilleraient la "légendaire" RFC 1321, je n'arrive pas à la faire fonctionner. Je copie-colle le contenu exactement comme suggéré, dans les 4 fichiers (global.h...), mais il y a un nombre important d'erreurs à la compilation, et cette librairie semble de toutes façons trop compliquée à comprendre et à mettre en oeuvre pour mes besoins, comparée à celle que j'ai trouvée.
Partager