forked from michelp/pgsodium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathencrypted_column.sql
79 lines (69 loc) · 2.05 KB
/
encrypted_column.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
CREATE SCHEMA IF NOT EXISTS pgsodium;
CREATE EXTENSION IF NOT EXISTS pgsodium WITH SCHEMA pgsodium;
-- This is a demonstration user to show that the pgsodium_keyiduser
-- role can be used to access only encryption functions by key_id,
-- this role can never access raw encryption keys.
CREATE ROLE auser;
GRANT pgsodium_keyiduser TO auser;
GRANT USAGE ON SCHEMA pgsodium TO auser;
SET ROLE auser;
CREATE TABLE IF NOT EXISTS test (
id bigserial primary key,
key_id bigint not null default 1,
nonce bytea not null,
data bytea
);
CREATE OR REPLACE VIEW test_view AS
SELECT id,
convert_from(
pgsodium.crypto_secretbox_open(
data,
nonce,
key_id),
'utf8') AS data FROM test;
CREATE OR REPLACE FUNCTION test_encrypt() RETURNS trigger
language plpgsql AS
$$
DECLARE
new_nonce bytea = pgsodium.crypto_secretbox_noncegen();
test_id bigint;
BEGIN
INSERT INTO test (nonce) VALUES (new_nonce) RETURNING ID INTO test_id;
UPDATE test SET
data = pgsodium.crypto_secretbox(
convert_to(new.data, 'utf8'),
new_nonce,
key_id)
WHERE id = test_id;
RETURN new;
END;
$$;
CREATE TRIGGER test_encrypt_trigger
INSTEAD OF INSERT ON test_view
FOR EACH ROW
EXECUTE FUNCTION test_encrypt();
CREATE OR REPLACE FUNCTION rotate_key(test_id bigint, new_key bigint)
RETURNS void LANGUAGE plpgsql AS $$
DECLARE
new_nonce bytea;
BEGIN
new_nonce = pgsodium.crypto_secretbox_noncegen();
UPDATE test SET
nonce = new_nonce,
key_id = new_key,
data = pgsodium.crypto_secretbox(
pgsodium.crypto_secretbox_open(
test.data,
test.nonce,
test.key_id),
new_nonce,
new_key)
WHERE test.id = test_id;
RETURN;
END;
$$;
\echo
\echo Try inserting some data in test_view like:
\echo " postgres=> insert into test_view (data) values ('this is one'), ('this is two');"
\echo Type RESET ROLE; to get back to previous user
insert into test_view (data) values ('this is one'), ('this is two');