Cette signature permet par exemple d'attester l'intégrité du contenu d'un fichier, d'un enregistrement d'une base de données, d'un message échangé, etc. parce qu'il est pratiquement impossible que deux contenus distincts produisent la même signature.
Ainsi :
Le principe est de calculer la valeur de quatre registres A, B, C, D dont les valeurs changent par application d'opérations paramétrées par leurs valeurs précédentes et le contenu du flux.
Pour casser la probabilité d'avoir deux mêmes signatures pour deux contenus distincts, obtenus par exemple par rotation ou translation l'un de l'autre, un paramétre lu dans une table sinusoïdale discrète est ajouté.
Voici l'algorithme Md5 :
A=0x67452301;
B=0xefcdab89;
C=0x98badcfe;
D=0x10325476;
AA=A;
BB=B;
CC=C;
DD=D;
A=Operation1(A,B,C,D, 0, 7, 1);
D=Operation1(D,A,B,C, 1, 12, 2);
C=Operation1(C,D,A,B, 2, 17, 3);
B=Operation1(B,C,D,A, 3, 22, 4);
A=Operation1(A,B,C,D, 4, 7, 5);
D=Operation1(D,A,B,C, 5, 12, 6);
C=Operation1(C,D,A,B, 6, 17, 7);
B=Operation1(B,C,D,A, 7, 22, 8);
A=Operation1(A,B,C,D, 8, 7, 9);
D=Operation1(D,A,B,C, 9, 12, 10);
C=Operation1(C,D,A,B, 10, 17, 11);
B=Operation1(B,C,D,A, 11, 22, 12);
A=Operation1(A,B,C,D, 12, 7, 13);
D=Operation1(D,A,B,C, 13, 12, 14);
C=Operation1(C,D,A,B, 14, 17, 15);
B=Operation1(B,C,D,A, 15, 22, 16);
A=Operation2(A,B,C,D, 1, 5, 17);
D=Operation2(D,A,B,C, 6, 9, 18);
C=Operation2(C,D,A,B, 11, 14, 19);
B=Operation2(B,C,D,A, 0, 20, 20);
A=Operation2(A,B,C,D, 5, 5, 21);
D=Operation2(D,A,B,C, 10, 9, 22);
C=Operation2(C,D,A,B, 15, 14, 23);
B=Operation2(B,C,D,A, 4, 20, 24);
A=Operation2(A,B,C,D, 9, 5, 25);
D=Operation2(D,A,B,C, 14, 9, 26);
C=Operation2(C,D,A,B, 3, 14, 27);
B=Operation2(B,C,D,A, 8, 20, 28);
A=Operation2(A,B,C,D, 13, 5, 29);
D=Operation2(D,A,B,C, 2, 9, 30);
C=Operation2(C,D,A,B, 7, 14, 31);
B=Operation2(B,C,D,A, 12, 20, 32);
A=Operation3(A,B,C,D, 5, 4, 33);
D=Operation3(D,A,B,C, 8, 11, 34);
C=Operation3(C,D,A,B, 11, 16, 35);
B=Operation3(B,C,D,A, 14, 23, 36);
A=Operation3(A,B,C,D, 1, 4, 37);
D=Operation3(D,A,B,C, 4, 11, 38);
C=Operation3(C,D,A,B, 7, 16, 39);
B=Operation3(B,C,D,A, 10, 23, 40);
A=Operation3(A,B,C,D, 13, 4, 41);
D=Operation3(D,A,B,C, 0, 11, 42);
C=Operation3(C,D,A,B, 3, 16, 43);
B=Operation3(B,C,D,A, 6, 23, 44);
A=Operation3(A,B,C,D, 9, 4, 45);
D=Operation3(D,A,B,C, 12, 11, 46);
C=Operation3(C,D,A,B, 15, 16, 47);
B=Operation3(B,C,D,A, 2, 23, 48);
A=Operation4(A,B,C,D, 0, 6, 49);
D=Operation4(D,A,B,C, 7, 10, 50);
C=Operation4(C,D,A,B, 14, 15 ,51);
B=Operation4(B,C,D,A, 5, 21, 52);
A=Operation4(A,B,C,D, 12, 6, 53);
D=Operation4(D,A,B,C, 3, 10, 54);
C=Operation4(C,D,A,B, 10, 15, 55);
B=Operation4(B,C,D,A, 1, 21, 56);
A=Operation4(A,B,C,D, 8, 6, 57);
D=Operation4(D,A,B,C, 15, 10, 58);
C=Operation4(C,D,A,B, 6, 15, 59);
B=Operation4(B,C,D,A, 13, 21, 60);
A=Operation4(A,B,C,D, 4, 6, 61);
D=Operation4(D,A,B,C, 11, 10, 62);
C=Operation4(C,D,A,B, 2, 15, 63);
B=Operation4(B,C,D,A, 9, 21, 64);
A+=AA;
B+=BB;
C+=CC;
D+=DD;
Le flux est toujours prolongé de la sorte que sa taille soit toujours un multiple de 64 octets :
Les registres A, B, C, D sont encodés obligatoirement dans l'ordre poids faible puis poids fort.
La variable T contient la table sinusoïdale discrète.
/****************************************************************/
Fonction F(X:Entier, Y:Entier, Z:Entier) Retourner Entier
/* Objet : Transformation F(X,Y,Z) = XY v not(X) Z. */
/****************************************************************/
Debut
Retourner (X&Y)|((~X)&Z);
Fin Fonction
/****************************************************************/
Fonction G(X:Entier, Y:Entier, Z:Entier) Retourner Entier
/* Objet : Transformation G(X,Y,Z) = XZ v Y not(Z). */
/****************************************************************/
Debut
Retourner (X&Z)|(Y&(~Z));
Fin Fonction
/****************************************************************/
Fonction H(X:Entier, Y:Entier, Z:Entier) Retourner Entier
/* Objet : Transformation H(X,Y,Z) = X xor Y xor Z. */
/****************************************************************/
Debut
Retourner X^Y^Z;
Fin Fonction
/****************************************************************/
Fonction I(X:Entier, Y:Entier, Z:Entier) Retourner Entier
/* Objet : Transformation I(X,Y,Z) = Y xor (X v not(Z)). */
/****************************************************************/
Debut
Retourner Y^(X|(~Z));
Fin Fonction
/****************************************************************/
Fonction Rotation(X:Entier, N:Entier) Retourner Entier
/* Objet : X <<< N. */
/****************************************************************/
Debut
Retourner (X<<N)|(X>>(32-N));
Fin Fonction
/****************************************************************/
Fonction Operation1(a:Entier, b:Entier, c:Entier, d:Entier, k:Entier, s:Entier, i:Entier) Retourner Entier
/* Objet : a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
/****************************************************************/
Debut
Retourner b + (Rotation((a + F(b,c,d) + Buffer[k] + T[i-1]), s));
Fin Fonction
/****************************************************************/
Fonction Operation2(a:Entier, b:Entier, c:Entier, d:Entier, k:Entier, s:Entier, i:Entier) Retourner Entier
/* Objet : a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
/****************************************************************/
Debut
Retourner b + (Rotation((a + G(b,c,d) + Buffer[k] + T[i-1]), s));
Fin Fonction
/****************************************************************/
Fonction Operation3(a:Entier, b:Entier, c:Entier, d:Entier, k:Entier, s:Entier, i:Entier) Retourner Entier
/* Objet : a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
/****************************************************************/
Debut
Retourner + (Rotation((a + H(b,c,d) + Buffer[k] + T[i-1]), s));
Fin Fonction
/****************************************************************/
Fonction Operation4(a:Entier, b:Entier, c:Entier, d:Entier, k:Entier, s:Entier, i:Entier) Retourner Entier
/* Objet : a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
/****************************************************************/
Debut
Retourner b + (Rotation((a + I(b,c,d) + Buffer[k] + T[i-1]), s));
Fin Fonction
T[0]=0xd76aa478;
T[1]=0xe8c7b756;
T[2]=0x242070db;
T[3]=0xc1bdceee;
T[4]=0xf57c0faf;
T[5]=0x4787c62a;
T[6]=0xa8304613;
T[7]=0xfd469501;
T[8]=0x698098d8;
T[9]=0x8b44f7af;
T[10]=0xffff5bb1;
T[11]=0x895cd7be;
T[12]=0x6b901122;
T[13]=0xfd987193;
T[14]=0xa679438e;
T[15]=0x49b40821;
T[16]=0xf61e2562;
T[17]=0xc040b340;
T[18]=0x265e5a51;
T[19]=0xe9b6c7aa;
T[20]=0xd62f105d;
T[21]=0x2441453;
T[22]=0xd8a1e681;
T[23]=0xe7d3fbc8;
T[24]=0x21e1cde6;
T[25]=0xc33707d6;
T[26]=0xf4d50d87;
T[27]=0x455a14ed;
T[28]=0xa9e3e905;
T[29]=0xfcefa3f8;
T[30]=0x676f02d9;
T[31]=0x8d2a4c8a;
T[32]=0xfffa3942;
T[33]=0x8771f681;
T[34]=0x6d9d6122;
T[35]=0xfde5380c;
T[36]=0xa4beea44;
T[37]=0x4bdecfa9;
T[38]=0xf6bb4b60;
T[39]=0xbebfbc70;
T[40]=0x289b7ec6;
T[41]=0xeaa127fa;
T[42]=0xd4ef3085;
T[43]=0x4881d05;
T[44]=0xd9d4d039;
T[45]=0xe6db99e5;
T[46]=0x1fa27cf8;
T[47]=0xc4ac5665;
T[48]=0xf4292244;
T[49]=0x432aff97;
T[50]=0xab9423a7;
T[51]=0xfc93a039;
T[52]=0x655b59c3;
T[53]=0x8f0ccc92;
T[54]=0xffeff47d;
T[55]=0x85845dd1;
T[56]=0x6fa87e4f;
T[57]=0xfe2ce6e0;
T[59]=0xa3014314;
T[59]=0x4e0811a1;
T[60]=0xf7537e82;
T[61]=0xbd3af235;
T[62]=0x2ad7d2bb;
T[63]=0xeb86d391;
d41d8cd98f00b204e9800998ecf8427e
900150983cd24fb0d6963f7d28e17f72
d174ab98d277d9f5a5611c2c9f419d9f
57edf4a22be3c955ac49da2e2107b67a