web-dev-qa-db-fra.com

Choisir le bon algorithme dans la fonction HashBytes

Nous devons créer une valeur de hachage des données nvarchar à des fins de comparaison. Il existe plusieurs algorithmes de hachage disponibles dans T-SQL, mais lequel parmi les meilleurs dans ce scénario?

Nous voulons nous assurer que le risque d'avoir une valeur de hachage en double pour deux valeurs nvarchar différentes est le minimum. Sur la base de mes recherches sur Internet, MD5 semble le meilleur. Est-ce correct? MSDN nous renseigne (lien ci-dessous) sur les algorithmes disponibles, mais aucune description sur lequel pour quelles conditions?

HASHBYTES (Transact-SQL)

Nous devons joindre deux tables sur deux colonnes nvarchar (max). Comme vous pouvez l'imaginer, la requête prend du temps à s'exécuter. Nous avons pensé qu'il serait préférable de conserver la valeur de hachage de chaque donnée nvarchar (max) et de faire la jointure sur les valeurs de hachage plutôt que les valeurs nvarchar (max) qui sont des blobs. La question est de savoir quel algorithme de hachage fournit l'unicité, de sorte que nous ne courons pas le risque d'avoir une valeur de hachage pour plus d'un nvarchar (max).

22
Sky

La fonction HASHBYTES ne prend que 8 000 octets en entrée. Parce que vos entrées sont potentiellement plus grandes que cela, les doublons dans la plage du champ qui est haché sera provoquent des collisions, quel que soit l'algorithme choisi. Considérez soigneusement la plage de données que vous prévoyez de hacher - en utilisant les 4000 premiers caractères est le choix évident, mais peut ne pas être le choix le mieux pour vos données .

Dans tous les cas, en raison de ce qu'est une fonction de hachage, même si les entrées sont de 8000 octets ou moins, la manière seulement pour garantir l'exactitude de 100% dans les résultats consiste à comparer les valeurs de base à certains point (lire: pas nécessairement d'abord). Période.

L'entreprise déterminera si une précision de 100% est requise ou non. Cela vous dira que (a) la comparaison des valeurs de base est requise , ou (b) vous devriez considérer pas comparant les valeurs de base - combien de précision doit être échangée pour les performances.

Bien que les collisions de hachage soient possibles dans un ensemble d'entrée unique, elles sont extrêmement rares, quel que soit l'algorithme choisi. L'idée globale d'utiliser une valeur de hachage dans ce scénario est de réduire efficacement les résultats de jointure à un ensemble plus gérable, pour ne pas nécessairement arriver à l'ensemble final de résultats immédiatement. Encore une fois, pour une précision de 100%, ceci ne peut pas être la dernière étape du processus. Ce scénario n'utilise pas de hachage à des fins de cryptographie, donc un algorithme tel que MD5 fonctionnera bien.

Il serait extrêmement difficile pour moi de justifier le passage à un algorithme SHA-x à des fins de "précision", car si l'entreprise va paniquer sur les minuscules possibilités de collision de MD5, il y a de fortes chances qu'elles paniquent également les algorithmes SHA-x ne sont pas parfaits non plus. Ils doivent soit accepter la légère imprécision, soit exiger que la requête soit exacte à 100% et en direct avec les implications techniques associées. Je suppose que si le PDG dort mieux la nuit en sachant que vous avez utilisé SHA-x au lieu de MD5, eh bien, très bien; cela ne signifie toujours pas grand-chose d'un point de vue technique dans ce cas.

En parlant de performances, si les tables sont principalement en lecture et que le résultat de la jointure est nécessaire fréquemment, envisagez d'implémenter une vue indexée pour éliminer la nécessité de calculer la jointure entière chaque fois qu'elle est demandée. Bien sûr, vous échangez le stockage pour cela, mais cela peut valoir la peine pour l'amélioration des performances, en particulier si une précision de 100% est requise.

Pour plus d'informations sur l'indexation des valeurs de chaînes longues, I a publié un article qui présente un exemple de procédure à suivre pour une seule table et présente les éléments à prendre en compte lors de la tentative du scénario complet dans cette question.

19
Jon Seigel

MD5 devrait être bien et la sortie peut être stockée dans un binaire (16). La probabilité d'une collision (voir paradoxe d'anniversaire ) est toujours très faible, même avec une grande taille d'échantillon physique. La sortie de SHA-1 prend 20 octets et la sortie de SHA-256 prend 32 octets. À moins que vous n'ayez un si grand nombre d'enregistrements que votre probabilité de collision d'anniversaire devienne significative (physiquement impossible ou du moins impraticable avec les technologies matérielles actuelles), elle sera probablement OK.

8

J'irais avec SHA-1, il est le meilleur des algorithmes disponibles et a le moins d'espérance de collision de tous (2 ^ 51 par rapport à MD5 qui est 2 ^ 20,96). MD5 s'est également révélé vulnérable aux collisions dans certains scénarios.

Sources:

http://en.wikipedia.org/wiki/SHA-1http://en.wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions#Cryptanalysishttp: //en.wikipedia.org/wiki/MD5

4
Mr.Brownstone

Je n'ai pas vu cela mentionné dans les réponses mais par MSDN :

Depuis SQL Server 2016 (13.x), tous les algorithmes autres que SHA2_256 et SHA2_512 sont obsolètes. Les algorithmes plus anciens (non recommandés) continueront de fonctionner, mais ils déclencheront un événement de dépréciation.

J'ai posé une question similaire donc c'est à vous de décider si vous souhaitez utiliser une fonction obsolète comme MD5 (si vous êtes sur 2016+). Vous pouvez effectuer des tests pour voir la différence de stockage et de performances entre MD5 et SHA2.

0
Gabe