From 28d064712089c358835c3ee2c235939acb547171 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 26 May 2020 13:48:17 +0900 Subject: [PATCH v12 3/3] Documentation update. --- doc/src/sgml/config.sgml | 47 +++++ doc/src/sgml/database-encryption.sgml | 276 ++++++++++++++++++++++++++ doc/src/sgml/filelist.sgml | 1 + doc/src/sgml/func.sgml | 99 +++++++++ doc/src/sgml/installation.sgml | 5 +- doc/src/sgml/postgres.sgml | 1 + doc/src/sgml/ref/initdb.sgml | 19 ++ doc/src/sgml/ref/pgupgrade.sgml | 7 + doc/src/sgml/storage.sgml | 5 + 9 files changed, 458 insertions(+), 2 deletions(-) create mode 100644 doc/src/sgml/database-encryption.sgml diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index b81aab239f..e133fb37ed 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -7615,6 +7615,39 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; + + Encryption Key Management + + + + cluster_passphrase_command (string) + + cluster_passphrase_command configuration parameter + + + + + This option specifies an external command to be invoked when a passphrase + for key management system needs to be obtained. + + + The command must print the passphrase to the standard output and exit + with code 0. In the parameter value, %p is + replaced by a prompt string. (Write %% for a + literal %.) Note that the prompt string will + probably contain whitespace, so be sure to quote adequately. A single + newline is stripped from the end of the output if present. The passphrase + must be at least 64 bytes. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + Client Connection Defaults @@ -9459,6 +9492,20 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + key_management_enabled (boolean) + + Key management configuration parameter parameter + + + + + Reports whether encryption key management is enabled for this cluster. + See for more information. + + + + data_directory_mode (integer) diff --git a/doc/src/sgml/database-encryption.sgml b/doc/src/sgml/database-encryption.sgml new file mode 100644 index 0000000000..1bb490feba --- /dev/null +++ b/doc/src/sgml/database-encryption.sgml @@ -0,0 +1,276 @@ + + + + Database Encryption + + + Server Side Encryption + + + + The purpose of database encryption is to protect the confidential data + stored in a database from being revealed. + + + + Encryption Key Management + + + PostgreSQL supports internal + Encryption Key Management System, which is designed + to manage the life cycles of cryptographic keys within the + PostgreSQL. This includes dealing with their + generation, storage, usage and rotation. + + + + Encryption key management system is enabled when + PostgreSQL is built with + --with-openssl and + is specified during + initdb. The cluster passphrase provided by + option during + initdb and the one generated by + in the + postgresql.conf must match, otherwise, the database + cluster will not start up. Please note that the cluster passphrase command + passed to initdb must return a passphrase equal or longer + than 64 bytes and less than 1024 bytes. For example. + +initdb -D dbname --cluster-passphrase-command="cat /path/to/passphrase-file" + + + + + Key Encryption Key(<acronym>KEK</acronym>) + + + During initdb process, the cluster passphrase provided + by is derived into + Key Encryption Key (KEK). + KEK encapsulates cryptographic keys managed inside + PostgreSQL described in + using by a way of authenticated + encryption described in before storing + the keys to a persistent storage. KEK must be stored + in a trusted key store, such as key vault software or services, or a + hardware security module. + + + + When a PostgreSQL server with encryption key + management enabled is started, the cluster_passphrase_command + parameter in postgresql.conf will be evaluated and + the cluster passphrase will be derived into + Key Encryption Key (KEK) in similar + ways as initdb. + + + + After that, the cryptographic keys will be retrieved from pg_cryptokeys + directory to be restored and integrity-checked by the key management + system using KEK. If this process fails, it is likely + that the cluster passphrase supplied to the cluster is not the same as that + supplied to the initdb process. The cluster will refuse + to start in this case and user has to manually correct the cluster passphrase. + + + + KEK is not stored physically within the + PostgreSQL server as they are designed + to be derived from the correctly configured cluster passphrase. + + + + + Key Derivations + + + Encryption key management system can manage multiple cryptographic keys + that have different purposes and usages within PostgreSQL. + Currently, encryption key management system manages no cryptographic key. + + + + + Key Protection + + + Key management system persists cryptographic keys to the disk after wrapping + them by KEK. This section describes how key maangement + system wrap and unwrap key. + + + + Key management system uses Encryption with Associated Data + (AEAD) to wrap cryptographic keys, which is a form of + encryption. In addition to provide a way to protect confidential data from + being revealed, it provides a way to check its integrity and authenticity + of some associated data. It follows Encrypt-Then-MAC approach, basing on + the composition of the Advanced Encryption Standard (AES) + in the Cipher Block Chaining (CBC) mode of operation + for encryption with random initialization vector(IV) and + the HMAC-SHA message authentication code + (MAC). + + + + Key management system uses two kinds of cryptographic keys for key wrapping: + + + + + + Encryption Key + + + Encryption key is 256 bits long randomly generate key. It is primarily used + to a key for encapsulate or restore data with AES256 + algorithm. + + + + + MAC Key + + + MAC key is 512 bits long randomly generated key. + SHA512 is the algorithm used along with the + MAC key to compute a cryptographic hash for integrity + check purposes. + + + + + + + + Key management systems's key wrapping algorithm is as follows: + + + + Generate random IV. + + + Add padding to the plaintext following PKCS#7 described in + RFC2315. + + + Encrypt padded plain text with the IV + using AES256 in CBC + mode. + + + Compute HMAC over the encrypted data. + + + Concatenate HMAC, IV + and encrypted ciphertext as the result of ciphertext. + + + + + + The length of the result ciphertext can be inferred from that of the plaintext + by following formula: + + Ciphertext Length = 64 + 16 + 16 * (floor(input_size / 16) + 1) + + + + + + Key Rotation Process + + + Encryption keys in general are not interminable, the longer the same key + is in use, the chance of it being breached increases. Performing key + rotation on a regular basis help meet standardized security practices + such as PCI-DSS + and it is a good practice in security to limit the number of encrypted + bytes available for a specific key version. The key lifetimes are based + on key length, key strength, algorithm and total number of bytes + enciphered. The key management system provides a efficient method to + perform key rotation. + + + + Please be aware that the phrase "key rotation" here + only refers to the rotation of KEK. The cryptographic + keys managed by encryption key management system are not rotated; they + will in fact be the same before and after a "key rotation". + This can be justified because the actual keys are never stored anywhere + physically, presented to user or captured in logging. What is being + rotated here is the KEK who is responsible for + encapsulating and restoring cryptographic keys. + + + + Since KEK is derived from a cluster passphrase, the + "key rotation" ultimately refers to the rotation of + cluster passphrase and deriving a new KEK from the + new cluster passphrase. The new KEK can then be used + to encapsulate all encryptions keys and store the new results in + pg_cryptokeys directory. + + + + To complete the cluster passphrase rotation, user needs to follow the + steps below: + + + + + Ensure the PostgreSQL server is running + correctly with KMS enabled. Passphrase rotation cannot be completed + with the server shut down. + + + + + Update parameter and + load such that the new command will return a new cluster passphrase. + + + + + In a session, execute pg_rotate_cluster_passphrase() + SQL function to initiate the rotation. The function returns true upon + successful key rotation and false if otherwise. + +=# SELECT pg_rotate_cluster_passphrase(); +pg_rotate_cluster_passphrase +------------------------------ + t +(1 row) + + + + + + + Upon successful cluster passphrase rotation, all managed cryptographic keys + will be re-encapsulated by the new KEK derived from the + new cluster passphrase. The new encapsulated keys will be stored in + pg_cryptokeys directory. Please note that the cryptographic + keys are the same as before; the rotation process only changes the + KEK that is used to encapsulate and verify the actual + cryptographic keys. This way, there is no need to decrypt all the encrypted + data with the old keys and re-encrypt them with the new. + + + + In case of a crash during the cluster passphrase rotation process, the key + management system is able to recover to the previous sets of cryptographic + keys the next time server starts up. This is possible because the key rotation + and encapsulation process are done on a separate temporary key directory called + pg_cryptokeys_tmp and it will replace + pg_cryptokeys and be deleted only when everything is + successfully finished. If the server starts with pg_cryptokeys_tmp folder present, + it would indicate that previous attempt of cluster passphrase rotation was not + completed. In this case, the server will discard pg_cryptokeys_tmp + folder and load the keys in pg_cryptokeys as usual. + + + + diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index 64b5da0070..8cf16ec1c9 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -48,6 +48,7 @@ + diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index b7c450ea29..2c6f5e6964 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -26699,4 +26699,103 @@ SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), + + Encryption Functions + + + Data Encryption Function + + The functions shown in + are for encrypting + and decrypting data with the SQL key described in + . + + + + Encryption <acronym>SQL</acronym> Functions + + + + Function + Return Type + Description + + + + + + + + pg_encrypt + + pg_encrypt(data text) + + + bytea + + + Encrypt the given data with the internal SQL key + + + + + + + pg_unwrap + + pg_decrypt(data bytea) + + + text + + + Decrypt the given data with the internal SQL key + + + + +
+
+ + + Key Management Functions + + The function shown in + are for encryption + key management described in . + + + + Encryption Key Management <acronym>SQL</acronym> Functions + + + + Function + Return Type + Description + + + + + + + pg_rotate_cluster_passphrase + + pg_rotate_cluster_passphrase() + + + boolean + + + Rotate the cluster passphrase. See + for details. + + + + + +
+
+
+ diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml index 4f89b4e930..2bf6a297b6 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -979,8 +979,9 @@ build-postgresql: Build with support for SSL (encrypted) - connections. This requires the OpenSSL - package to be installed. configure will check + connections and key management. This requires the + OpenSSL package to be installed. + configure will check for the required header files and libraries to make sure that your OpenSSL installation is sufficient before proceeding. diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml index c41ce9499b..a96196c85d 100644 --- a/doc/src/sgml/postgres.sgml +++ b/doc/src/sgml/postgres.sgml @@ -170,6 +170,7 @@ break is not needed in a wider output rendering. &wal; &logical-replication; &jit; + &database-encryption; ®ress; diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml index 1635fcb1fd..1e26939379 100644 --- a/doc/src/sgml/ref/initdb.sgml +++ b/doc/src/sgml/ref/initdb.sgml @@ -163,6 +163,25 @@ PostgreSQL documentation + + + + + This option specifies an external command to be invoked when a passphrase + for key management system needs to be obtained. + + + The command must print the passphrase to the standard output and exit + with code 0. In the parameter value, %p is + replaced by a prompt string. (Write %% for a + literal %.) Note that the prompt string will + probably contain whitespace, so be sure to quote adequately. A single + newline is stripped from the end of the output if present. The passphrase + must be at least 64 bytes. + + + + diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml index 319d613296..24e288a617 100644 --- a/doc/src/sgml/ref/pgupgrade.sgml +++ b/doc/src/sgml/ref/pgupgrade.sgml @@ -821,6 +821,13 @@ psql --username=postgres --file=script.sql postgres is down. + + During the upgrade pg_upgrade copies the all internal keys + to the new cluster. If you want to upgrade from the old cluster that enables + the key management to the new cluster that also enables, you must use the same + cluster_passphrase_command to both clusters. Otherwise + pg_upgrade fails due to mismatching the cluster passphrase. + diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml index 3234adb639..05e9b262a4 100644 --- a/doc/src/sgml/storage.sgml +++ b/doc/src/sgml/storage.sgml @@ -77,6 +77,11 @@ Item Subdirectory containing transaction commit timestamp data + + pg_cryptokeys + Subdirectory containing cryptographic keys + + pg_dynshmem Subdirectory containing files used by the dynamic shared memory -- 2.23.0