Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS)

From: Bruce Momjian <bruce(at)momjian(dot)us>
To: Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Tomas Vondra <tomas(dot)vondra(at)2ndquadrant(dot)com>, Antonin Houska <ah(at)cybertec(dot)at>, Haribabu Kommi <kommi(dot)haribabu(at)gmail(dot)com>, "Moon, Insung" <Moon_Insung_i3(at)lab(dot)ntt(dot)co(dot)jp>, Ibrar Ahmed <ibrar(dot)ahmad(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: [Proposal] Table-level Transparent Data Encryption (TDE) and Key Management Service (KMS)
Date: 2019-05-09 16:44:20
Message-ID: 20190509164420.n533d7pa2oxbobaa@momjian.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, May 8, 2019 at 09:32:08AM -0400, Robert Haas wrote:
> On Tue, May 7, 2019 at 2:10 AM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
> > > > That better not be true. If you have a design where reading the WAL
> > > > lets you get *any* encryption key, you have a bad design, I think.
> >
> > How does the startup process decrypt WAL during recovery without
> > getting any encryption key if we encrypt user data in WAL by multiple
> > encryption keys?
>
> The keys have to be supplied from someplace outside of the database
> system. I am imagining a command that gets run with the key ID as an
> argument and is expected to print the key out on standard output for
> the server to read.

Agreed.

> I am not an encryption expert, but it's hard for me to imagine this
> working any other way. I mean, if you store the keys that you need
> for decryption inside the database, isn't that the same as storing
> your house key in your house, or your car key in your car? If you
> store your car key in the car, then either the car is locked from the
> outside, and the key is useless to you, or the car is unlocked from
> the outside, and the key is just as available to a thief as it is to
> you. Either way, it provides no security. What you do is keep your
> car key in your pocket or purse; if you try to start the car, it
> "requests" the key from you as proof that you are entitled to start
> it. I think the database has to work similarly, except that rather
> than protecting the act of "starting" the database, each key is
> requested the first time it's needed, when it's discovered that we
> need to decrypt some data encrypted with that key.

Two-tier encryption usually stores the encrypted data keys in the
database, and the key access password is supplied externally.
pgcryptokey does this:

http://momjian.us/download/pgcryptokey/

+------------------------+
| |
| key access password |
| |
| +------------------+ |
| |encrypted_data_key| |
| +------------------+ |
| |
+------------------------+

> > > > Well, what threat are you trying to protect against?
> >
> > Data theft bypassing PostgreSQL's ACL, for example a malicious user
> > thefts storage devices and reads database files directly.
> >
> > I'm thinking that only users who have an access privilege of the
> > database object can get encryption key for the object. Therefore, when
> > a malicious user stole an encryption key by breaking the access
> > control system if we suppose data at rest encryption to serve as a yet
> > another access control layer we have to use the same encryption key
> > for WAL as that we used for database file. But I thought that we
> > should rather protect data from that situation by access control
> > system and managing encryption keys more robustly.
>
> I don't really follow that logic. If the encryption keys are managed
> robustly enough that they cannot be stolen, then we only need one. If
> there is still enough risk of key theft that we care to protect
> against it, we can't use a dedicated key for the WAL without
> increasing the risk.

You can change the key access password periodically by just reencrypting
the encrypted data keys with the new key access password.

Because you need to reencrypt all data when you change the encrypted
data key, you probably need to have at least two such keys active at a
time. I think you need an API that allows applications to just use the
most recent key, and another API which allows you to select keys by
version number. pgcryptokey does this by allowing specification of a
encrypted data key by name or key_id.

It might be necessary to allow decryption to try several versions of a
key to see which one decrypts the data. While this is possible with PGP
because there is a checksum payload, it isn't possible with AES256
because the input/output sizes are the same. Checking for a valid 8k
block format or WAL format might work.

--
Bruce Momjian <bruce(at)momjian(dot)us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ As you are, so once was I. As I am, so you will be. +
+ Ancient Roman grave inscription +

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2019-05-09 17:20:53 Re: PG12, PGXS and linking pgfeutils
Previous Message Tom Lane 2019-05-09 16:22:39 Re: What's the point of allow_system_table_mods?