PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 21/12/2015 15:54:21

gchanteloube
Membre

SHA différent suite à un cryptage bf (UTF8)

Bonjour à tous,

Je vous fait part de mon souci, je suis dessus depuis un bon petit moment et je ne comprends pas du tout d'où peut venir l'erreur ...
J'ai un champ crypté, avec comme donnée en claire : "mamané"

J'arrive bien à le récupérer :

convert_from(decrypt(name::bytea, 'salt', 'bf'), 'UTF-8') => "mamané"

On est bon sur ça !

Maintenant je crypte cette valeur :

encode(public.digest('mamané', 'sha1'), 'hex') => "2bfb316cf461d1a884e0b24c4d90de0bfe25f04f"

Mais là est tout le souci ... Si je fais la même chose mais sur le champ name (comme au dessus), je n'obtiens pas le même hash ...

encode(public.digest(convert_from(decrypt(name::bytea, 'salt', 'bf'), 'UTF-8'), 'sha1'), 'hex') => "e16053f9fba5b1ef75b76eab82370c3264ee6263"

Je n'arrive pas à l'expliquer ...
Merci beaucoup pour vos réponses.

G.

Hors ligne

#2 28/12/2015 16:13:58

dverite
Membre

Re : SHA différent suite à un cryptage bf (UTF8)

Quel est le type de la colonne name? text/varchar(N) ou bytea?

Quel est son contenu brut?

Quel est l'encodage serveur et l'encodage client (show server_encoding; et show client_encoding; )

Ces questions car le cast de TEXT en BYTEA produit un résultat qui dépend de l'encodage.

Exemple en base UTF-8:

=> select 'é'::bytea;
bytea 
--------
\xc3a9

En base LATIN9:

=> select 'é'::bytea;
bytea
-------
\xe9


A ce propos quelque chose qui pique les yeux est que é est un E accentué encodé en UTF-8 mais interprété en ISO. Ca arrive soit quand le client_encoding n'est pas bon, soit parce que le contenu a été doublement converti LATIN1->UTF-8 puis encore LATIN1->UTF-8, la deuxième passe corrompant le contenu.

Ca n'explique pas le résultat montré dans la question, mais ça laisse penser que le contenu de la colonne est mal encodé dès le départ.



Quand on applique digest() à un texte, l'encodage des caractères compte aussi. Le même texte ne donnera pas le même digest dans un encodage ou un autre, car l'algorithme de digest s'applique aux octets, par aux caractères.

UTF-8:

=> select digest('é', 'SHA1');
                   digest                   
--------------------------------------------
\xbf15be717ac1b080b4f1c456692825891ff5073d

LATIN9:

=> select digest('é', 'SHA1');
                   digest                   
--------------------------------------------
  \x1599e9fa41ec68c80230491902786bee889f5bcb

Hors ligne

Pied de page des forums