Bien que le MD5 ne soit plus utilisé pour l’encryption, il est toujours utilisé pour valider l’authenticité et la conformité des fichiers.
Qu’est-ce qu’un MD5
Un md5 est une chaine de 16 caractères composée de symboles hexadécimaux. Il s’agit en réalité du nom de l’algorithme utilisé pour générer la chaine.
Comme indiqué précédemment son usage est le contrôle d’intégrité des fichier, par exemple lors du partage d’un fichier, on peut mettre à disposition le MD5 afin de contrôler que le téléchargement du fichier s’est bien passé ou que le fichier n’a pas été modifié entre temps.
Pour la suite nous aurons besoin d’un fichier, par simplicité j’utiliserai un simple .txt qui contient la phrase « This is not a test! » présent dans mon répertoire de l’ifs.
Fichier dans l’ifs | /home/jl/file.txt |
Contenu du fichier | This is not a test! |
md5 | EDA20FB86FE23401A5671734E4E55A12 |
QSH – md5sum
La première méthode pour générer le MD5 d’un fichier est d’utiliser la commande unix md5sum via QSH :
$ /QOpenSys/pkgs/bin/md5sum /home/jl/file.txt
eda20fb86fe23401a5671734e4e55a12 /home/jl/md5.txt
La fonction retourne le hash et le chemin du fichier.
RPGLE – _cipher
Il est également possible de générer le MD5 via RPG en exploitant la procédure externe cipher.
Je ne m’épancherai pas sur son implémentation complète ici, car bien plus complexe que les deux autres méthodes présentées. De plus, passer par cette méthode, n’est plus le sens de l’histoire.
// Déclaration de la procédure
dcl-pr cipher extproc('_cipher');
*n pointer value;
*n pointer value;
*n pointer value;
end-pr;
// Appel de la procédure
cipher(%ADDR(receiver) : %ADDR(controls) : %ADDR(source));
Lien vers la documentation IBM pour plus d’informations :
https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/rzatk/CIPHER.htm
SQL – hash_md5
En sql on retrouve la fonction hash_md5, qui retourne le hash d’une chaine de caractère passée en paramètre.
❗ Attention à l’encodage de votre chaine de caractères. ❗
Pour que le résultat soit cohérent entre différents systèmes il faut commencer par convertir la chaine de caractère en UTF-8 :
VALUES CAST('This is not a test!' AS VARCHAR(512) CCSID 1208); -- 1208 = UTF-8
-- Retour : This is not a test!
Le résultat est plutôt flagrant ! D’accord pas vraiment… Par contre si on regarde la valeur hexadécimale de la chaine avec et sans conversion :
VALUES HEX('This is not a test!');
-- Retour : E38889A24089A2409596A3408140A385A2A34F
VALUES HEX(CAST('This is not a test!' AS VARCHAR(512) CCSID 1208));
-- Retour : 54686973206973206E6F742061207465737421
Le hachage se fait en hexadécimal, donc le résultat ne serait pas le même sans conversion préalable.
Il suffit maintenant de hacher notre chaine de caractères :
VALUES HASH_MD5(CAST('This is not a test!' AS VARCHAR(512) CCSID 1208));
-- Retour : EDA20FB86FE23401A5671734E4E55A12
On obtient donc la même valeur que celle que l’on a obtenu précédemment (puisque que le contenu de notre fichier est strictement égale à cette chaine de caractère).
La dernière étape est de générer le MD5 directement à partir du fichier, pour cela il suffit d’utiliser la fonction GET_BLOB_FROM_FILE :
VALUES HASH_MD5(GET_BLOB_FROM_FILE('/home/jl/file.txt')) WITH CS;
-- Retour : EDA20FB86FE23401A5671734E4E55A12
Autres algorithmes de hash
Il existe d’autres algorithmes de hash qui permettent de hacher du texte et des fichiers.
Trois autres algorithmes sont généralement disponibles :
- sha1 (qui génère une chaine de 20 de long)
- sha256 (qui génère une chaine de 32 de long)
- sha512 (qui génère une chaine de 64 de long)
QSH
Commande | Résultat |
/qopensys/pkgs/bin/sha1sum /home/jl/file.txt | 10e2e89feb9287eea7a4b7b849b7a380d95c05b9 /home/jl/file.txt |
/qopensys/pkgs/bin/sha256sum /home/jl/file.txt | ff8fb31c076b42fd63377e7ea4747f98c34291ac6e5f53cfd3940913bc9d7d37 /home/jl/file.txt |
/qopensys/pkgs/bin/sha512sum /home/jl/file.txt | 658efb990d2765ca65adb570daa198ef6bee55e39d3a7b7fa31270c35fdf9ee523ce638dea4796ea8923a2ad428e23d23b62175b26494fa8fdca49d5e85ce502 /home/jl/file.txt |
SQL
Syntaxe | Résultat |
VALUES HASH_SHA1(CAST(‘This is not a test!’ AS VARCHAR(512) CCSID 1208)); | 10E2E89FEB9287EEA7A4B7B849B7A380D95C05B9 |
VALUES HASH_SHA256(CAST(‘This is not a test!’ AS VARCHAR(512) CCSID 1208)); | FF8FB31C076B42FD63377E7EA4747F98C34291AC6E5F53CFD3940913BC9D7D37 |
VALUES HASH_SHA512(CAST(‘This is not a test!’ AS VARCHAR(512) CCSID 1208)); | 658EFB990D2765CA65ADB570DAA198EF6BEE55E39D3A7B7FA31270C35FDF9EE523CE638DEA4796EA8923A2AD428E23D23B62175B26494FA8FDCA49D5E85CE502 |
Pour plus de détails
MD5 : https://fr.wikipedia.org/wiki/MD5
md5sum : https://fr.wikipedia.org/wiki/Md5sum
Fonction sql HASH() : https://www.ibm.com/docs/en/i/7.4?topic=sf-hash-md5-hash-sha1-hash-sha256-hash-sha512
Fonction sql BLOB() : https://www.ibm.com/docs/en/i/7.4?topic=functions-get-blob-from-file
CCSID : https://www.ibm.com/docs/en/i/7.4?topic=information-ccsid-values-defined-i
cypher : https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/rzatk/CIPHER.htm