2015-11-13 21:53 GMT+01:00 Esneiker Enriquez Cabrera <eenriq...@cav.desoft.cu>: > Escribo porque estoy probando guardar información encriptada en la base de > datos con codificación utf8 y todo resulta bien, excepto cuando la > información tiene caracteres especiales, se guarda basura. > A continuación les pongo un ejemplo. > select > encode(decrypt(encrypt('telefónico','password','3des'),'password','3des'::text), > 'escape'::text); > el resultado que me retorna es “telef\303\263nico”, en lugar de telefónico. > Espero que me puedan indicar cómo hacer el tratamiento correcto.
Esto huele a lo de siempre, UTF-8 es una forma de codificar texto en bytes, la criptografia va en bytes, tenemos el encoding de la base de datos por un lado, nos hemos liado.etc etc... No te lo puedo asegurar, pero el hecho de que necesites encode ya te da una pista. Encrypt toma bytea como datos, PEEERO, tu le has dado un texto fiandote de la conversion por defecto, decrypt devuelve bytea. Luego coges y le dices que te lo imprima en escape, y lo hace bien, de hecho : cdrs=> show client_encoding; client_encoding ----------------- UTF8 (1 row) cdrs=> select encode('telefónico', 'escape'); encode ------------------- telef\303\263nico (1 row) El problema es que el decrypt/encrypt es el equivalente a pasat telefónico a bytea: cdrs=> select 'telefónico'::bytea; bytea -------------------------- \x74656c6566c3b36e69636f (1 row) cdrs=> select encode('telefónico'::bytea, 'escape'); encode ------------------- telef\303\263nico (1 row) Y lo que tu quieres es que te interprete esos bytes como utf8, no que te los imprima escapados, para eso necesitarias una funcion de conversion de bytes a string, como por ejemplo: cdrs=> select convert_from('telefónico'::bytea, 'UTF-8'); convert_from -------------- telefónico (1 row) No te lo puedo probar porque no tengo instaladas las crypto, pero juraria que es eso. Por cierto, si lo es tu codigo tiene un problema, que dejas la conversion de texto a bytea a merced del encoding de la conexion y otroas cosas, lo que no es recomendable, particularmente en criptografia. Probablement tus problemas vienen de que la conversion no es reversible: cdrs=> select 'telefónico'::bytea::text; text -------------------------- \x74656c6566c3b36e69636f (1 row) Las cosas te iran mejor/mas simples, si al igual que apareas encrypt/decrypt haces lo mismo con convert_from, convert_to, asi te aseguras de que lo hace en el encoding que tu le dices independientemente de la conexion: cdrs=> select convert_from(convert_to('telefónico','UTF-8'), 'UTF-8'); convert_from -------------- telefónico (1 row) Que funciona con otros encoding ( que soporten los caracteres que usas ): cdrs=> select convert_from(convert_to('telefónico','LATIN-1'), 'LATIN-1'); convert_from -------------- telefónico (1 row) A pesar de que: cdrs=> values(convert_to('telefónico','LATIN-1'), 'LATIN-1') union values(convert_to('telefónico','UTF-8'), 'UTF-8'); column1 | column2 --------------------------+--------- \x74656c6566c3b36e69636f | UTF-8 \x74656c6566f36e69636f | LATIN-1 (2 rows) Si haces esto se ve la simetria, select(convert_from(decrypt(encrypt(convert_to...... no te fies nunca de las conversiones por defecto cuando estas usando bytea, siempre se revuelven y te muerden donde menos lo esperas. Saludos. Francisco Olarte. - Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda@postgresql.org) Para cambiar tu suscripci�n: http://www.postgresql.org/mailpref/pgsql-es-ayuda