jeudi, août 30, 2012

Fonction de hachage MD5 dans DB2

La fonction de hachage fournie  par défaut dans DB2DBMS_UTILITY.GET_HASH_VALUE, peut rapidement présenter ses limites lorsqu'il s'agit de minimiser les collisions.

Attention aux collisions
Les deux instructions suivantes nous retourne la même et unique valeur de hachage 1007044402

1 SELECT DBMS_UTILITY.GET_HASH_VALUE(
'370583815295F84346683861EUR55BE',
0,
2147483647) FROM sysibm.sysdummy1;
2 SELECT DBMS_UTILITY.GET_HASH_VALUE(
'52963397472P567015371118EUR87AT',
0,
2147483647) FROM sysibm.sysdummy1;
Un résultat qui rend cette fonction peu utile pour ne pas dire inutilisable dans plusieurs cas où la résistance aux collisions est vraiment un critère nécessaire.  Avant de juger si  GET_HASH_VALUE  peut nous être utile il faut se faire une idée sur sa résistance aux collisions, or un rapide test sur  2 millions de lignes de chaines de caractères générées aléatoirement et de longueur variable nous donne un pourcentage de collision qui se rapproche de 1%.  Ce qui peut être acceptable pour certains, mais qui ne l'est pas pour beaucoup d'autres.

MD5 mise en place
La solution évidente à ce problème et qui sans doute nous vient tout de suite à l'esprit est la fonction MD5 mais le soucis c'est que cette fonction est totalement absente de DB2, du moins elle absente à l'heure de la rédaction de cette note sur la version DB2 9.7.x.x.  Pour pouvoir utiliser MD5, il faudra donc passer par une fonction (UDF) externe qui pourrait être écrite en C ou en Java.

Voici comment faire:

  1. Télécharger une bibliothèque C prévue à cet effet qui s'appelle db2-auth-routines, ici.
  2. Afin de pouvoir compiler cette bibliothèque vous aurez besoin des bibliothèques de Apache Runtime Project, notamment: apr et apr-util, téléchargeables ici.
  3. Extraire les archives pour compiler dans l'ordre apr, apr-util et db2-auth-routines.
  4. apr ne nécessite aucune configuration préalable et n'est nécessaire que pour le besoin de compilation, donc vous pourrez paramétrer la variable prefix lorsque vous lancez le ./configure.

    ./configure --prefix=mon_chemin_pour_apr  
    make
    make install
  5. apr-util dépend de apr, donc il faudra spécifier le chemin de apr

    ./configure --with-apr=mon_chemin_pour_apr  
    make
    make install
  6. Avant de compiler db2-auth-routines, éditer le fichier de compilation makertn pour configurer le chemin vers apr, apr-util et aussi la bibliothèque de DB2 
  7. Lancer la compilation et l'enregistrement des nouvelles fonctions dans DB2
    ./makertn
    db2 connect to basededonnees user utilisateur using motdepasse;
    db2 -tvf register.ddl
  8. Connectez vous a la base et tester

    1 SELECT md5('370583815295F84346683861EUR55BE'), md5('52963397472P567015371118EUR87AT')
    2 FROM sysibm.sysdummy1;