Le cadre .NET est livré avec 6 algorithmes de hachage différents :
- MD5 : 16 octets (Temps pour hacher 500MB : 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 a des performances différentes ; MD5 étant la plus rapide et RIPEMD la plus lente.
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 très faciles à utiliser pour l'identification.
MD5 est cependant vulnérable à attaques par collision SHA-1 est également vulnérable, mais à un degré moindre.
Dans quelles conditions dois-je utiliser quel algorithme de hachage ?
Les questions auxquelles je suis vraiment curieux de voir des réponses sont les suivantes :
-
Faut-il se méfier de MD5 ? 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) ?
-
Dans quelle mesure RIPEMD est-il meilleur que SHA1 (s'il est meilleur) ? il est 5 fois plus lent à calculer mais la taille du 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 point de référence 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();
}
15 votes
Le fait que vous mentionniez que md5 s'inscrit dans le format GUID (16 octets) suggère un malentendu fondamental. Un hash n'est pas garanti unique, mais il est rare (et difficile à falsifier s'il est utilisé dans un sens cryptographique) et dérivé de la chose dont il est le hash, alors qu'un GUID est, lui, unique mais sans rapport avec le contenu de la chose qu'il identifie. Ils sont utilisés à des fins très différentes.
2 votes
C'est vrai que ça n'a rien à voir, c'est juste un fait pratique et spécifique à la mise en œuvre. Je comprends que l'on ne peut pas faire tenir l'infini dans 16 octets. Vous pouvez avoir des collisions avec n'importe quel algorithme de hachage.
5 votes
De plus, un guide est unique dans la pratique. En théorie, si vous continuez à générer des guides, vous obtiendrez des doublons.
3 votes
Vous avez vraiment ne devrait pas bourrer un hash dans un GUID, même si cela correspond. Exemple le plus simple : deux copies du même fichier devraient avoir des GUIDs différents, mais le même hash. Les 8 premières lettres du nom d'une personne tiennent également très bien dans 16 octets.
0 votes
Si les performances sont importantes, l'utilisation de bibliothèques tierces peut être une bonne idée. Par exemple, pour hacher des messages courts, OpenSSL est environ 10 fois plus rapide que le MD5 intégré à .net.
0 votes
Je ne pense pas que .net ait une implémentation de RIPEMD, je ne peux trouver qu'une implémentation de RIPEMD-160. RIPEMD est cassé, RIPEMD-160 ne l'est pas.
0 votes
@BarryWark Je pense que je devrais souligner que l'ensemble du système de contrôle de source Git dépend des hachages SHA1 (ou SHA256 ?) qui sont uniques pour chaque fichier, chaque répertoire et chaque livraison dans l'ensemble du référentiel. La probabilité d'une collision accidentelle est si faible que vous pouvez compter sur le fait que cela se produise. après notre planète n'est plus habitable :-) Donc, pour de nombreux cas d'utilisation, hash = GUID.
0 votes
@Andrey Tarantsov, je pense que vous avez raison mais vous sous-estimez également la vitesse à laquelle la crypto-science et surtout l'informatique progressent. Il est probable que dans 1 ou 2 ans au plus, SHA-1 sera cassé (SHA-256 restera probablement sûr pendant encore 5 ou 6 ans).
2 votes
@user2332868 La rupture de SHA-1 n'a aucun effet sur la probabilité de accidentel les collisions. Lorsqu'une intention malveillante est une menace pour votre utilisation, je pense que choisir aveuglément n'importe quelle fonction de hachage est une erreur, et vous devez passer du temps à faire une analyse risque/coût pour votre cas spécifique.
0 votes
Mais il est toujours plus sûr de respecter les normes de sécurité.
0 votes
@dbkk Selon le codage, les 16 premières lettres du nom d'une personne peuvent tenir dans 16 octets, ou même les 18 premiers, ou peut-être seulement 4.
0 votes
@dbkk Vous êtes supposée pour remplir un hash dans un UUID. C'est exactement ce que les UUIDs de type 3 et de type 5 sont .
Type 3:
Espace de nom avec hachage MD5.Type 5:
Espace de nom avec hachage SHA-1. Source : rfc4122 - Un espace de nommage URN (Universally Unique IDentifier - UUID) . Bonus :Type 1
: Date et MAC.Type 4
: Random0 votes
@IanBoyd intéressant, mais dans la section 4.3, la RFC précise que les "noms" (à partir desquels un hachage est généré) sont uniques à "l'espace de noms". Dans l'exemple des fichiers, le contenu des fichiers ne satisfait PAS à cette contrainte.
0 votes
@dbkk Ils le font, une fois que vous aurez suivi les règles . Vous devez également définir certains nibbles à certaines valeurs. Mais l'utilisation d'un hachage comme guide est parfaitement acceptable.