Je travaille sur un projet .NET 3.5 et j'ai besoin d'une valeur de hachage de 32 bits. Il ne semble pas y avoir de méthodes dans les classes .NET Cryptography qui retournent un hachage 32 bits (MD5 est 128 bits, SHA1 est 160 bits, etc.). J'ai implémenté une classe CRC32, mais je trouve que les fonctions de hachage SHA1 et MD5 qui existent déjà sont beaucoup plus rapides. Y aura-t-il un problème (c'est-à-dire un risque accru de collisions) avec moi en utilisant la fonction de hachage SHA1 et en rompant simplement les 32 premiers bits à stocker comme valeur de hachage?Les 32 premiers bits d'un hachage SHA1 de 160 bits sont-ils un substitut acceptable pour un hachage CRC32?
Répondre
Sauf si vous voulez les fonctionnalités supplémentaires du CRC32 (étant un code linéaire), vous devriez être en mesure de couper la sortie à 32 bit. Le fait de couper la sortie de certaines fonctions de hachage cryptographiques nuit à sa sécurité vis-à-vis de la résistance aux collisions est un problème de recherche ouvert (des exemples construits «non naturels» existent si je me souviens bien). Mais NIST (probablement avec l'approbation de la NSA) a utilisé la technique de coupe pour obtenir le SHA-224 de SHA-256 de toute façon (voir article about SHA in wikipedia). EDIT: le CRC32 permet de détecter (et peut-être de corriger) les erreurs sur un seul bit, tandis qu'une fonction de hachage cryptographique devrait avoir la propriété de ne pas trouver deux entrées ayant la même valeur de hachage.
Connaissez-vous le "paradoxe de l'anniversaire" (voir à nouveau wikipedia)? Avec une somme de contrôle de 32 bits, vous vous attendez à une collision (c'est-à-dire, deux entrées avec la même valeur de hachage) lorsque vous avez environ 2^16 entrées, et vous voulez hacher beaucoup plus d'entrées. (Relecture de votre commentaire, cela pourrait ne pas poser de problème pour vous.)
Si c'est assez bon pour le NIST, c'est assez bon pour moi. – raven
Si vous n'avez pas l'intention d'utiliser les 32 bits à des fins de chiffrement, alors vous devriez être OK. Sinon, je ne compterais pas sur les premiers 32 bits ayant la même distribution que l'ensemble du hachage. Pourquoi ne pouvez-vous pas simplement utiliser le hachage plus large qui est disponible?
CRC32 est probablement raisonnable pour vos besoins. Cela a été discuté dans this question.
En termes de tronçonnage d'une primitive de hachage, la seule application fortement utilisée est SSL/TLS Pseudo Random Function (PRF) qui est utilisée pour générer des clés. Il utilise les HMAC, les seed et les labels pour générer autant d'octets que nécessaire en hachant plusieurs fois et en tronquant la quantité d'octets dont vous avez besoin.
Quant à votre question cependant, vous pouvez lire la sortie du hachage dans de Int32, puis les XOR ensemble si vous êtes paranoïaque:
static void Main()
{
int xorCrc = GetHashedCrc(new SHA1Cng(), new byte[] {0xDE, 0xAD, 0xBE, 0xEF});
}
private static int GetHashedCrc(HashAlgorithm algorithm, byte[] bytesToHash)
{
byte[] hash = algorithm.ComputeHash(bytesToHash);
int totalInt32s = hash.Length/sizeof(int);
int result = 0;
for(int i = 0; i < totalInt32s; i++)
{
int currentInt = BitConverter.ToInt32(hash, sizeof(int)*i);
result = result^currentInt;
}
return result;
}
Mauvaise idée. Cela ne fait qu'ajouter de la complexité et n'a aucun avantage. Si vous utilisez SHA1, HMAC, etc., le résultat est déjà assez "aléatoire". Couper le résultat est juste trouver. C'est la méthode par exemple que le NIST propose d'obtenir des hachages plus courts (par exemple SHA-224 ou SHA-384) ou pour des HMACS plus courtes. – Accipitridae
D'accord. Je cherchais simplement un moyen d'utiliser tous les bits, mais vous avez raison de dire que cela ne fait pas de différence de sécurité et que cela coûte des instructions supplémentaires. –
Compte tenu de l'hypothèse selon laquelle une fonction de hachage distribue ses entrées aussi au-dessus de son codomaine, il semble logique de supposer qu'il se répartira également sur tout sous-ensemble de celui-ci. Cependant, l'utilisation d'une fonction de hachage 32 bits "native" sera probablement le meilleur choix. Peut-être quelqu'un de plus dans la question peut nous fournir une meilleure raison que mon instinct :)
Pourquoi n'utilisez-vous pas simplement string.GetHashCode(). Il est conçu pour calculer une valeur de hachage 32 bits et produire peu de collisions données données du monde réel. Bien sûr, ce n'est pas sécurisé, mais votre question ne comprend pas cela comme une exigence.
String.GetHashCode présente l'inconvénient de produire des résultats différents dans les modes 32 et 64 bits. Il change également de temps en temps lorsque Microsoft publie la nouvelle version .NET. Cela devient un problème lorsque vous persistez votre hachage ou même l'envoyer sur le réseau. – Constantin
Que faites-vous que vous ne pouvez pas stocker le hachage SHA-1 de 20 caractères? En outre, CRC32 n'est pas un hachage, c'est un mécanisme de détection d'erreur de transmission, donc si vous avez besoin d'une détection d'erreur, un hachage n'est pas vraiment la façon de le faire. – jmucchiello
Le hachage de 4 octets a été choisi dans l'intérêt d'économiser de l'espace. Le hachage sera utilisé pour les blocs de données de contrôle provenant d'un dispositif de surveillance et il peut y en avoir des dizaines de millions. Nous verrons, peut-être stocker tout cela ne sera pas un problème. Vous avez dit quelque chose d'intéressant. Quelle est exactement la différence entre un "mécanisme de détection d'erreur de transmission" et un hachage? Force cryptographique (cette application particulière n'a pas besoin de ça)? – raven
Auto-plug éhonté: cmdhashgen soutient CRC32 et est dérivé de HashAlgorithm, donc il peut juste être utilisé de la même manière que les autres, consultez Crc32.cs: http://cmdtools.codeplex.com/ –