Appearance
Encrypting Sensitive Data
You can use the ENCRYPT_KS
and DECRYPT_KS
SQL functions to protect access to sensitive character data, such as Personally Identifiable Information (PII). Encryption functions scramble the input data they receive, rendering it unreadable to any user or role who does not have both the privileges and the access key required to decrypt it. Authorized users can run the encryption functions against any valid SQL expression that evaluates to a character string.
You can also create tables with encrypted columns; in this case, those columns are encrypted automatically when data is loaded or inserted. You do not need to call the ENCRYPT_KS
function explicitly.
The Yellowbrick implementation of the ENCRYPT_KS
and DECRYPT_KS
functions contains code under the OpenSSL license.
Configuring Encryption for SQL Access
The ENCRYPT_KS
and DECRYPT_KS
functions are backed by an integrated Kubernetes secrets manager (or keystore). The system looks up "secrets" when keys are specified as arguments to encryption functions.
Before trying to use SQL encryption functions, complete the following configuration steps:
- Make sure encryption is enabled by running the following
SHOW
command:
premdb=> show ybd_secrets_manager;
ybd_secrets_manager
---------------------
k8ss
(1 row)
The ybd_secrets_manager
parameter defines access to the secrets manager. If this parameter is not set to k8ss
, use an ALTER SYSTEM
command to set it, then reload the configuration:
premdb=> alter system set ybd_secrets_manager to k8ss;
WARNING: Will be effective after the next server configuration reload, or after the next server restart in the case of parameters that can only be changed at server start
ALTER SYSTEM
premdb=> select pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)
premdb=> show ybd_secrets_manager;
ybd_secrets_manager
---------------------
k8ss
(1 row)
- Grant
CREATE
privilege per schema to users and roles who will be able to create, delete, and describe keys created in that schema. (This is the same type of privilege that you would grant to users who are going to create tables and other objects.) For example:
premdb=# grant create on schema public to yb100;
GRANT
- Create keys with the
CREATE KEY
SQL command, using a valid hexadecimal string to define a "secret." Keys belong to the database and schema where you create them. For example:
premdb=# CREATE KEY yb100key SECRET 'a1b2c3d4e5f0';
CREATE KEY
This command creates a key for the public schema in the premdb
database. The secret for the key is saved in the encryption keystore. (Authorized users pass in the key name, not its associated secret, when they run encryption functions.) Administrators can query the sys.key
view to return a list of keys that have been created per database and schema. For example:
premdb=# select * from sys.key;
key_id | name | schema_id | owner_id | creation_time
--------+----------+-----------+----------+-------------------------------
16480 | yb100key | 2200 | 16007 | 2019-11-07 15:26:30.577896-08
(1 row)
- Grant
ENCRYPT
and/orDECRYPT
access on keys to specific users and roles. For example:
premdb=# grant all on key yb100key to yb100;
GRANT
This example grants ENCRYPT
and DECRYPT
privileges to members of the role named yb100
.
- Test the functions by encrypting and then decrypting a column from a table:
premdb=# create table encrypted_names as select encrypt_ks(nickname, yb100key) enc from team;
SELECT 50
premdb=# select decrypt_ks(enc,yb100key) from encrypted_names;
decrypt_ks
------------
Gunners
Villains
Tykes
Blues
Rovers
...
For more details about the commands used in these steps, see:
Calling the Functions
The ENCRYPT_KS
and DECRYPT_KS
functions take the following arguments:
- An input expression (required), which must evaluate to a character string. For example, this could be a column name, the concatenation of values from two columns, or the result of another function.
- The name of the key (required). Users specify keys to ensure that the data is encrypted and decrypted consistently every time the same source data is accessed. Keys are mapped to secrets stored in the vault.
- One of three standard AES algorithms, all of which use Output Feedback Mode (OFB):
- AES with a 128-bit key (the default)
- AES with a 192-bit key
- AES with a 256-bit key
- An optional "initialization vector" provides an additional level of obfuscation. This parameter provides an efficient way to re-scramble the encrypted data without having to rebuild the overall character mapping that is generated when a new key is used. Instead of using a different key for each function call, you can use the same key and adjust the vector. Taken together, the key and vector parameters function like a login credential with two levels of privacy and security.
Using ybunload
, you can unload data with a query that contains the ENCRYPT_KS
function. You can reload the data as is with ybload
, then decrypt it with a query or CTAS
statement that uses the DECRYPT_KS
function. (You cannot load and decrypt data in one step with ybload
.)
Creating Tables with Encrypted Columns
When you create a table with encrypted columns, data inserted or loaded into those columns is automatically encrypted using the ENCRYPT_KS
function. In turn, encrypted data is automatically decrypted when it is selected by users who have DECRYPT
privilege on the key (and SELECT
privilege on the table). Users writing queries against encrypted columns do not have to specify the DECRYPT_KS
function. Users who do not have DECRYPT
privilege on the key see the stored encrypted values.
The CREATE TABLE statement supports the ENCRYPTED
column constraint for VARCHAR
columns only. For example, the following table is defined with three encrypted VARCHAR
columns: weekly_wages
, dob
(date of birth), and cob
(country of birth):
premdb=# create table player(
playerid bigint not null,
teamid smallint not null,
seasonid smallint not null,
firstname varchar(30),
lastname varchar(30),
position char(1),
dob varchar(100) encrypted with(COLUMN_ENCRYPTION_KEY=playerkey,ENCRYPTION_TYPE=RANDOMIZED,ALGORITHM='AES_256_OFB'),
weekly_wages varchar(100) encrypted with(COLUMN_ENCRYPTION_KEY=playerkey,ENCRYPTION_TYPE=RANDOMIZED,ALGORITHM='AES_256_OFB'),
avg_mins_per_match double precision,
matches_played real,
cob varchar(100) encrypted with(COLUMN_ENCRYPTION_KEY=playerkey,ENCRYPTION_TYPE=RANDOMIZED,ALGORITHM='AES_256_OFB'));
CREATE TABLE
premdb=# \d player
Table "public.player"
Column | Type | Modifiers
--------------------+------------------------+---------------------------------------------------------------------------------------------------------------------------
playerid | bigint | not null
teamid | smallint | not null
seasonid | smallint | not null
firstname | character varying(30) |
lastname | character varying(30) |
position | character(1) |
dob | character varying(100) | encrypted with (column_encryption_key = premdb.public.playerkey, encryption_type = randomized, algorithm = 'aes_256_ofb')
weekly_wages | character varying(100) | encrypted with (column_encryption_key = premdb.public.playerkey, encryption_type = randomized, algorithm = 'aes_256_ofb')
avg_mins_per_match | double precision |
matches_played | real |
cob | character varying(100) | encrypted with (column_encryption_key = premdb.public.playerkey, encryption_type = randomized, algorithm = 'aes_256_ofb')
Distribution: Hash (playerid)
This table is then loaded from a CSV file with rows like these:
15,23,27,Virgil,Van Dijk,D,07-08-1991,180000,87.6345,37.4,Netherlands
16,24,27,David,Silva,M,01-08-1986,250000,79.6723,30.5,Spain
17,22,27,Jamie,Vardy,F,01-11-1987,80000,77.1986,31.6,England
...
User bobr
belongs to a role with SELECT
privilege on the table, but this role does not have DECRYPT
privilege on the key. Therefore, user bobr
sees rows like these:
premdb=> select * from player where playerid between 15 and 17;
-[ RECORD 1 ]------+-------------------------------------------------------------
playerid | 15
teamid | 23
seasonid | 27
firstname | Virgil
lastname | Van Dijk
position | D
dob | CVdbnbTmmeYaaA4SZfOV590jszv8Ooj09zGHsIlB7Q9WhjS2ywNMrg9JVA==
weekly_wages | CYJzBAQSvlufeMDyWtH2Yr5TA7Ao+ulFpP3eY2SwBSVpNb/DlQjn
avg_mins_per_match | 87.6345
matches_played | 37.4
cob | CYz7BPoHAjpNJF0E+O8K/gU8yhRj7oFgcCKvb37lG/LlSep/9M2UbFHHECo=
-[ RECORD 2 ]------+-------------------------------------------------------------
playerid | 16
teamid | 24
seasonid | 27
firstname | David
lastname | Silva
position | M
dob | CUdWko/n2n6SbaaVb39Ck6RYwPH9+intp+oP0p7Uq5M+mMIPQa6iV+wMzA==
weekly_wages | CXWWk/rZxpNJM5LtBfW32nx+eoQ/0X9NexX236RNAC3N4533++rD
avg_mins_per_match | 79.6723
matches_played | 30.5
cob | CXjnwR9g7+iFgQi8IfBsZRYpmj4+sgkmlvSHrZFdCnZmfG+q4YI=
-[ RECORD 3 ]------+-------------------------------------------------------------
playerid | 17
teamid | 22
seasonid | 27
firstname | Jamie
lastname | Vardy
position | F
dob | CeVFkbgdYq2ZOjW7s0E/RQSWlN8W+TsvwYVu8W5EDDPRuRFJS5Mwu7/QyQ==
weekly_wages | CRMmOw16X8foeWOsq0N+x7kTNXTTFsHo5aXXeH6yzhwmeWu1XMI=
avg_mins_per_match | 77.1986
matches_played | 31.6
cob | Cf9r4Q60m/5FtYWSa8jwu3164z0SoL8UDxuz0p3FPQaRQmTjU7oL7w==
If user bobr
is granted DECRYPT
privilege on the key (either directly or via a role in which he has membership), all of the column values are visible in clear text:
premdb=# grant decrypt on key playerkey to bobr;
GRANT
premdb=# \c premdb bobr
You are now connected to database "premdb" as user "bobr".
premdb=> select * from player where playerid between 15 and 17;
playerid | teamid | seasonid | firstname | lastname | position | dob | weekly_wages | avg_mins_per_match | matches_played | cob
----------+--------+----------+-----------+----------+----------+------------+--------------+--------------------+----------------+-------------
15 | 23 | 27 | Virgil | Van Dijk | D | 07-08-1991 | 180000 | 87.6345 | 37.4 | Netherlands
16 | 24 | 27 | David | Silva | M | 01-08-1986 | 250000 | 79.6723 | 30.5 | Spain
17 | 22 | 27 | Jamie | Vardy | F | 01-11-1987 | 80000 | 77.1986 | 31.6 | England
(3 rows)
For more details about creating tables with encrypted columns, see CREATE TABLE. For details about the specific algorithms used to encrypt data, see Encryption and Decryption Algorithms.
In This Section
Parent topic:Database Administration