Le framework .NET est livré avec 6 algorithmes de hachage différents:
- MD5: 16 octets (temps de hachage 500 Mo: 1462 ms)
- SHA-1: 20 octets (1644 ms)
- SHA256: 32 octets (5618 ms)
- SHA384: 48 octets (3839 ms)
- SHA512: 64 octets (3820 ms)
- RIPEMD: 20 octets (7066 ms)
Chacune de ces fonctions fonctionne différemment; MD5 étant le plus rapide et RIPEMD étant le plus lent.
MD5 a l'avantage de s'intégrer dans le type Guid intégré; et c'est la base de l'UUID de type 3 . Le hachage SHA-1 est la base de l'UUID de type 5. Ce qui les rend vraiment faciles à utiliser pour l'identification.
MD5 est cependant vulnérable aux attaques par collision , SHA-1 est également vulnérable, mais dans une moindre mesure.
Dans quelles conditions dois-je utiliser quel algorithme de hachage?
Les questions particulières auxquelles je suis vraiment curieux de voir des réponses sont:
MD5 n'est-il pas digne de confiance? Dans des situations normales, lorsque vous utilisez l'algorithme MD5 sans intention malveillante et qu'aucun tiers n'a d'intention malveillante, vous attendez-vous à TOUTES les collisions (c'est-à-dire deux octets arbitraires [] produisant le même hachage)
À quel point RIPEMD est-il meilleur que SHA1? (si c'est mieux) il est 5 fois plus lent à calculer mais la taille de hachage est la même que SHA1.
Quelles sont les chances d'obtenir des collisions non malveillantes lors du hachage de noms de fichiers (ou d'autres chaînes courtes)? (Par exemple, 2 noms de fichiers aléatoires avec le même hachage MD5) (avec MD5 / SHA1 / SHA2xx) En général, quelles sont les chances de collisions non malveillantes?
C'est le benchmark que j'ai utilisé:
static void TimeAction(string description, int iterations, Action func) {
var watch = new Stopwatch();
watch.Start();
for (int i = 0; i < iterations; i++) {
func();
}
watch.Stop();
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}
static byte[] GetRandomBytes(int count) {
var bytes = new byte[count];
(new Random()).NextBytes(bytes);
return bytes;
}
static void Main(string[] args) {
var md5 = new MD5CryptoServiceProvider();
var sha1 = new SHA1CryptoServiceProvider();
var sha256 = new SHA256CryptoServiceProvider();
var sha384 = new SHA384CryptoServiceProvider();
var sha512 = new SHA512CryptoServiceProvider();
var ripemd160 = new RIPEMD160Managed();
var source = GetRandomBytes(1000 * 1024);
var algorithms = new Dictionary<string,HashAlgorithm>();
algorithms["md5"] = md5;
algorithms["sha1"] = sha1;
algorithms["sha256"] = sha256;
algorithms["sha384"] = sha384;
algorithms["sha512"] = sha512;
algorithms["ripemd160"] = ripemd160;
foreach (var pair in algorithms) {
Console.WriteLine("Hash Length for {0} is {1}",
pair.Key,
pair.Value.ComputeHash(source).Length);
}
foreach (var pair in algorithms) {
TimeAction(pair.Key + " calculation", 500, () =>
{
pair.Value.ComputeHash(source);
});
}
Console.ReadKey();
}