Re: Internal key management system
От | Masahiko Sawada |
---|---|
Тема | Re: Internal key management system |
Дата | |
Msg-id | CA+fd4k46HHDiPE_39F1C=B+F-1pbinFPsW-GyPzvxSz+pZx1Qw@mail.gmail.com обсуждение исходный текст |
Ответ на | Re: Internal key management system (Cary Huang <cary.huang@highgo.ca>) |
Ответы |
Re: Internal key management system
(Robert Haas <robertmhaas@gmail.com>)
Re: Internal key management system (Fabien COELHO <coelho@cri.ensmp.fr>) |
Список | pgsql-hackers |
On Sat, 2 May 2020 at 07:17, Cary Huang <cary.huang@highgo.ca> wrote: > > Hi all > > I am sharing here a document patch based on top of kms_v10 that was shared awhile back. This document patch aims to covermore design details of the current KMS design and to help people understand KMS better. Please let me know if you haveany more comments. Thank you for your patch! I've changed the internal key management patch much. Here is the summary of the changes: I've changed the key manager so that it can manage multiple cryptographic keys up to 128 bytes long. Currently, all keys managed by the key manager need to be pre-defined, and the key manager has only one cryptographic key, SQL key which is used to encrypt/decrypt data via SQL function interface. But it's easy to add new keys for potential use cases, for example when we need some keys for transparent data encryption. When the server starting up, the key manager unwraps the internal key and load to the shared memory. Perhaps we need to protect the load key memory space from being swapped out using mlock() but it's not implemented yet. For SQL interface, I've changed the patch much. The encryption process we called 'wrap' and 'unwrap' is actually authenticated encryption with associated data[1] (AEAD) which is not a dedicated way to wrap cryptographic keys. I renamed pg_wrap() and pg_unwrap() to pg_encrypt() and pg_decrypt() to make these function names more understandable. These SQL functions encrypt/decrypt data using the SQL key. So currently, there are two usages of pg_encrypt () and pg_decrypt() functions to encrypt database data: First, we can encrypt data directly using these SQL functions. That way, users don't need to manage and know the encryption key, moreover, we enable users to use AEAD without pgcrypto. Second, by wrapping the user secret key using these SQL functions we can use them in conjunction with the cryptographic functions provided by pgcrypto. Users can wrap their secret key by SQL key via pg_encrypt(), and then use the user secret unwrapped by pg_decrypt() when SELECT, INSERT, UPDATE, and DELETE operation. Here is an example: -- Wrap user secret and save to 'key' variable, or somewhere =# SELECT pg_encrypt('user password') as key \gset -- Encrypt/decrypt user data with the secret string 'user password' which is obtained by unwrapping 'key' variable. =# INSERT INTO tbl VALUES (pgp_sym_encrypt('abc123', pg_decrypt(:'key'))); =# SELECT pgp_sym_decrypt(col, pg_decrypt(:'key')) FROM tbl; However, this usage has a downside that user secret can be logged to server logs when log_statement = 'all' or an error happens. To deal with this issue I've created a PoC patch on top of the key manager patch which adds a libpq function PQencrypt() to encrypt data and new psql meta-command named \encrypt in order to encrypt data while eliminating the possibility of the user data being logged. PQencrypt() just calls pg_encrypt() via PQfn(). Using this command the above example can become as follows: -- Encrypt user secret via PQfn and store it to 'key variable, or somewhere =# \encrypt Enter data: Enter it again: encrypted data: \x8e17079ed65f570f5adcac9023cb5d079708f34563e62f3f9f1f0f26c7ad4ecf7b90dc199d7b3bbf663c8800d98162d02dc30da247ca4c825f3240c4a7c419a7c8785d9f7f974d0ed310f179ecbbab1ecf38ec48d74d41dd13544595d45d5ec9 =# \set key '\x8e17079ed65f570f5adcac9023cb5d079708f34563e62f3f9f1f0f26c7ad4ecf7b90dc199d7b3bbf663c8800d98162d02dc30da247ca4c825f3240c4a7c419a7c8785d9f7f974d0ed310f179ecbbab1ecf38ec48d74d41dd13544595d45d5ec9 -- Encrypt/decrypt user data with the secret string 'user password' which is obtained by unwrapping 'key' variable. =# INSERT INTO tbl VALUES (pgp_sym_encrypt('abc123', pg_decrypt(:'key'))); =# SELECT pgp_sym_decrypt(col, pg_decrypt(:'key')) FROM tbl; BTW after some research, I've found Always Encrypted which is a database encryption feature provided by SQL Server uses a quite similar approach called AEAD_AES_256_CBC_HMAC_SHA_256[2]. AEAD_AES_256_CBC_HMAC_SHA_256 is actually derived from from the specification draft[3]. For documentation, I've incorporated the proposed update by Cary and add some descriptions, especially for AEAD. I've separate the patch into several pieces so it can be reviewed easily. Here is a short description of each patch: 0001 patch introduces AES256-CBC and HMAC-SHA512 to src/common. These functions are enabled only when --with-openssl environment. 0002 patch introduces AEAD algorithm to src/common. 0003 patch introduces the key management module that is split into two parts: utility code and backend code. The key manager reads/writes cryptographic keys, verifies the given passphrase, wraps and unwraps keys using AEAD. Currently the key manager has only one internal key, SQL key. 0004 patch added two SQL functions: pg_encrypt() and pg_decrypt() 0005 and 0006 patch introduce regression tests and documentation respectively. 0007 patch is a PoC patch that adds PQencrypt() function and psql's \encrypt meta-command to encrypt data so that target data are not logged. Regards, [1] https://en.wikipedia.org/wiki/Authenticated_encryption#Authenticated_encryption_with_associated_data_(AEAD) [2] https://docs.microsoft.com/ja-jp/sql/relational-databases/security/encryption/always-encrypted-cryptography?view=sql-server-ver15 [3] https://tools.ietf.org/html/draft-mcgrew-aead-aes-cbc-hmac-sha2-05. -- Masahiko Sawada http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Вложения
- v11-0007-POC-libpq-encryption-protocol.patch
- v11-0003-Add-key-management-module.patch
- v11-0006-Documentation-update.patch
- v11-0004-Add-encrypt-and-decrypt-SQL-functions.patch
- v11-0005-Add-regression-tests-for-key-management.patch
- v11-0002-Add-AEAD-functions-for-both-frontend-and-backend.patch
- v11-0001-Add-encryption-functions-for-both-frontend-and-b.patch
В списке pgsql-hackers по дате отправления: