Das .NET Framework wird mit 6 verschiedenen Hashing-Algorithmen geliefert:
- MD5: 16 Bytes (Zeit bis zum Hash 500 MB: 1462 ms)
- SHA-1: 20 Bytes (1644 ms)
- SHA256: 32 Bytes (5618 ms)
- SHA384: 48 Bytes (3839 ms)
- SHA512: 64 Bytes (3820 ms)
- RIPEMD: 20 Bytes (7066 ms)
Jede dieser Funktionen funktioniert anders. MD5 ist das schnellste und RIPEMD das langsamste.
MD5 hat den Vorteil, dass es in den eingebauten Guid-Typ passt. und es ist die Basis der Typ 3 UUID . SHA-1-Hash ist die Basis der UUID vom Typ 5. Das macht sie wirklich einfach zur Identifizierung zu verwenden.
MD5 ist jedoch anfällig für Kollisionsangriffe , SHA-1 ist ebenfalls anfällig, jedoch in geringerem Maße.
Unter welchen Bedingungen sollte ich welchen Hashing-Algorithmus verwenden?
Besondere Fragen, auf die ich sehr gespannt bin, sind:
Ist MD5 nicht vertrauenswürdig? Unter normalen Umständen, wenn Sie den MD5-Algorithmus ohne böswillige Absicht verwenden und kein Dritter böswillige Absichten hat, würden Sie JEDE Kollision erwarten (dh zwei beliebige Bytes [], die denselben Hash erzeugen).
Wie viel besser ist RIPEMD als SHA1? (wenn es besser ist) es ist 5 mal langsamer zu berechnen, aber die Hash-Größe ist die gleiche wie bei SHA1.
Wie hoch ist die Wahrscheinlichkeit, dass beim Hashing von Dateinamen (oder anderen kurzen Zeichenfolgen) nicht böswillige Kollisionen auftreten? (ZB 2 zufällige Dateinamen mit demselben MD5-Hash) (mit MD5 / SHA1 / SHA2xx) Wie hoch sind im Allgemeinen die Chancen für nicht böswillige Kollisionen?
Dies ist der Benchmark, den ich verwendet habe:
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();
}