I am having a problem with encrypting a field. Have tried different methods but seem to be hitting a wall. New to postgres psql, so probably really stupid logical mistake, but... Either run into: HINT: No function matches the given name and argument types. You might need to add explicit type casts. or: ERROR: function encrypt(text, unknown, unknown) does not exist
Lets create a table:
create table test_table (t_unencrypted text, t_encrypted bytea);
insert data into it:
insert into test_table (t_unencrypted) values ('Brown fox hopped over the blue fence');
Now lets see if we can get value from one column and encrypt it into another column:
update test_table set t_encrypted = encrypt(t_unencrypted,'A0000000000000000000000000000001','AES');
Nope:
ERROR: function encrypt(text, unknown, unknown) does not exist
LINE 1: update test_table set t_encrypted = encrypt(t_unencrypted,'A...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Allright, this did not work, lets try another way:
DO $$
declare
unenctxt text;
enctxt bytea;
BEGIN
select t_unencrypted from test_table into unenctxt;
select into enctxt (select (encrypt(unenctxt, 'A0000000000000000000000000000001', 'AES')));
insert into test_table (t_encrypted) values (enctxt);
END; $$;
Nope, still no luck:
ERROR: function encrypt(text, unknown, unknown) does not exist
Okay, I give up, lets make sure that it actually works and make it into a procedure and a trigger.
test=# select (encrypt('Brown fox hopped over the blue fence', 'A0000000000000000000000000000001', 'AES'));
encrypt
----------------------------------------------------------------------------------------------------
\xb5b6bfc073f1cc4a1be4133866c9b8acacb859f192077ff3bbf70927963726026ced37091cbc16786d56e630b32108b4
(1 row)
Yay! So, lets create a trigger and procedure as follows:
test=# CREATE FUNCTION encrypt_txt()
RETURNS TRIGGER AS
$func$
BEGIN
NEW.t_encrypted := encrypt(NEW.t_encrypted, 'A0000000000000000000000000000001', 'AES');
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
CREATE FUNCTION
test=# CREATE OR REPLACE TRIGGER encrypt_data
BEFORE INSERT ON test_table
FOR EACH ROW
EXECUTE PROCEDURE encrypt_txt();
CREATE TRIGGER
test=# insert into test_table (t_unencrypted,t_encrypted) values ('Brown fox hopped over the blue fence','Brown fox hopped over the blue fence');
INSERT 0 1
test=# select * from test_table;
t_unencrypted | t_encrypted
--------------------------------------+----------------------------------------------------------------------------------------------------
Brown fox hopped over the blue fence |
Brown fox hopped over the blue fence | \xb5b6bfc073f1cc4a1be4133866c9b8acacb859f192077ff3bbf70927963726026ced37091cbc16786d56e630b32108b4
Cool, it works! Now lets insert data via help of a trigger:
test=# insert into test_table (t_encrypted) select t_unencrypted from test_table where t_encrypted is null;
ERROR: column "t_encrypted" is of type bytea but expression is of type text
LINE 1: insert into test_table (t_encrypted) select t_unencrypted fr...
^
HINT: You will need to rewrite or cast the expression.
Well, crap.
And yes I have tried casting a type via ::, but it makes no actual difference. It seems that when inserting via select the trigger actually does not fire ?
Have also tried trigger for update and different tactics and loops but this post is long already. And there seems to be some logical error on my part.
And yes, I am intentionally using low level encrypt instead of pgp_sym or pgp_pub.
Help ?:)