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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
<!-- doc/src/sgml/database-encryption.sgml -->
<chapter id="database-file-encryption">
<title>Cluster File Encryption</title>
<indexterm zone="database-file-encryption">
<primary>Cluster File Encryption</primary>
</indexterm>
<para>
The purpose of cluster file encryption is to prevent users with read
access to the directories used to store database files and write-ahead
log from being able to access the data stored in those files.
For example, when using cluster file encryption, users who have read
access to the cluster directories for backup purposes will not be able
to decrypt the data stored in the these files.
</para>
<para>
Cluster file encryption uses two levels of encryption. The first level
is data encryption keys, specifically keys zero and one. Key zero is
the key used to encrypt database heap and index files which are stored in
the file system, plus temporary files created during database operation.
Key one is used to encrypt write-ahead log (WAL) files. Two different
keys are used so that primary and standby servers can use different zero
(heap/index/temp) keys, but the same one (WAL) key, so that these keys
can eventually be rotated by switching the primary to the standby as
and then changing the WAL key.
</para>
<para>
The second level of encryption is a key used to encrypt first-level
keys. This type of key is often referred to as a Key Encryption Key
(<acronym>KEK</acronym>). This key is <emphasis>not</emphasis> stored
in the file system, but provided at <command>initdb</command> time and
each time the server is started. This key prevents anyone with access
to the database directories from decrypting the data because they do
not know the second-level key which encrypted the first-level keys
which encrypted the database cluster files.
</para>
<sect1 id="encryption-file-encryption">
<title>Initialization</title>
<para>
Cluster file encryption is enabled when
<productname>PostgreSQL</productname> is built
with <literal>--with-openssl</literal> and <xref
linkend="app-initdb-cluster-key-command"/> is specified
during <command>initdb</command>. The cluster key
provided by the <option>--cluster-key-command</option>
option during <command>initdb</command> and the one generated
by <xref linkend="guc-cluster-key-command"/> in the
<filename>postgresql.conf</filename> must match for the database
cluster to start. Note that the cluster key command
passed to <command>initdb</command> must return a key of
64 hexadecimal characters. For example.
<programlisting>
initdb -D dbname --cluster-key-command='ckey_passphrase.sh'
</programlisting>
</para>
</sect1>
<sect1 id="key-encryption-key">
<title>Internals</title>
<para>
During the <command>initdb</command> process, if
<option>--cluster-key-command</option> is specified, two data-level
encryption keys are created. These two keys are then encrypted with
the key enryption key (KEK) supplied by the cluster key command before
being stored in the database directory. The key or passphrase that
derives the key must be supplied from the terminal or stored in a
trusted key store, such as key vault software, hardware security module.
</para>
<para>
If the <productname>PostgreSQL</productname> server has
been initialized to require a cluster key, each time the
server starts the <filename>postgresql.conf</filename>
<varname>cluster_key_command</varname> command will be executed
and the cluster key retrieved. The data encryption keys in the
<filename>pg_cryptokeys</filename> directory will then be decrypted
using the supplied key and integrity-checked to ensure it
matches the initdb-supplied key. If this check fails, the
server will refuse to start.
</para>
<para>
The data encryption keys are randomly generated and are of 128, 192,
or 256-bits in length. They are encrypted by the key encryption key
(KEK) using Advanced Encryption Standard (<acronym>AES256</acronym>)
encryption in Galois/Counter Mode (<acronym>GCM</acronym>), which also
provides KEK authentication.
</para>
</sect1>
</chapter>
|