PostgreSQL – Fix Base64 Encoded SHA512 Digest String Equality Test

postgresqlpostgresql-10

I have the following table

   Column    |            Type            | Collation | Nullable |
-------------+----------------------------+-----------+----------+-------------------
 name        | text                       |           | not null |
 code        | text                       |           | not null |

I insert new elements using the following INSERT

INSERT INTO table(name, code)
    VALUES('SOMENAME',encode(digest(gen_random_uuid()::text,'sha512'), 'base64')) ;

Now when I try to SELECT against the code field:

SELECT * FROM tabel WHERE code='K5HUaRwxsXzkAl3NaWHbBkvnYEK/...';

It returns an empty set.

----------
(0 rows)

The puzzling part is that it seems to break only for SHA512 with base64 encoding , it works just fine if I use SHA256 or if I change the encoding to HEX.

I have a feeling that it might be a bug, but am I missing something?

Best Answer

With 64 bytes, the sha512 digest is large enough that encoding it in base64 generates a newline character (LF) in the result (at about 76 characters from the start).

Probably what goes wrong is that newline character not being correctly reinjected in the SELECT query, where you truncated the literal with an ellipsis (so we can't actually see it):

SELECT * FROM tabel WHERE code='K5HUaRwxsXzkAl3NaWHbBkvnYEK/...';

To inject a newline, you may use the E'...' syntax and have \n to denote that character.

SELECT * FROM tabel WHERE code= E'K5HUaR.....\n...rest of string';