Re: Transparent column encryption

From: Tomas Vondra <tomas(dot)vondra(at)enterprisedb(dot)com>
To: Jacob Champion <pchampion(at)vmware(dot)com>, "peter(dot)eisentraut(at)enterprisedb(dot)com" <peter(dot)eisentraut(at)enterprisedb(dot)com>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Transparent column encryption
Date: 2021-12-07 21:21:32
Message-ID: 1be3fd0e-959a-29e3-5f63-9c3dff9e7cb2@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 12/7/21 19:02, Jacob Champion wrote:
> On Tue, 2021-12-07 at 16:39 +0100, Peter Eisentraut wrote:
>> On 06.12.21 21:44, Jacob Champion wrote:
>>> I think reusing a zero IV will potentially leak more information than
>>> just equality, depending on the cipher in use. You may be interested in
>>> synthetic IVs and nonce-misuse resistance (e.g. [1]), since they seem
>>> like they would match this use case exactly. (But I'm not a
>>> cryptographer.)
>>
>> I'm aware of this and plan to make use of SIV. The current
>> implementation is just an example.
>
> Sounds good.
>
>>> Have you given any thought to AEAD? As a client I'd like to be able to
>>> tie an encrypted value to other column (or external) data. For example,
>>> AEAD could be used to prevent a DBA from copying the (encrypted) value
>>> of my credit card column into their account's row to use it.
>>
>> I don't know how that is supposed to work. When the value is encrypted
>> for insertion, the client may know things like table name or column
>> name, so it can tie it to those. But it doesn't know what row it will
>> go in, so you can't prevent the value from being copied into another
>> row. You would need some permanent logical row ID for this, I think.
>
> Sorry, my description was confusing. There's nothing preventing the DBA
> from copying the value inside the database, but AEAD can make it so
> that the copied value isn't useful to the DBA.
>
> Sample case. Say I have a webapp backed by Postgres, which stores
> encrypted credit card numbers. Users authenticate to the webapp which
> then uses the client (which has the keys) to talk to the database.
> Additionally, I assume that:
>
> - the DBA can't access the client directly (because if they can, then
> they can unencrypt the victim's info using the client's keys), and
>
> - the DBA can't authenticate as the user/victim (because if they can,
> they can just log in themselves and have the data). The webapp might
> for example use federated authn with a separate provider, using an
> email address as an identifier.
>
> Now, if the client encrypts a user's credit card number using their
> email address as associated data, then it doesn't matter if the DBA
> copies that user's encrypted card over to their own account. The DBA
> can't log in as the victim, so the client will fail to authenticate the
> value because its associated data won't match.
>
>>>> This is not targeting PostgreSQL 15. But I'd appreciate some feedback
>>>> on the direction.
>>>
>>> What kinds of attacks are you hoping to prevent (and not prevent)?
>>
>> The point is to prevent admins from getting at plaintext data. The
>> scenario you show is an interesting one but I think it's not meant to be
>> addressed by this. If admins can alter the database to their advantage,
>> they could perhaps increase their account balance, create discount
>> codes, etc. also.
>
> Sure, but increasing account balances and discount codes don't lead to
> getting at plaintext data, right? Whereas stealing someone else's
> encrypted value seems like it would be covered under your threat model,
> since it lets you trick a real-world client into decrypting it for you.
>
> Other avenues of attack might depend on how you choose to add HMAC to
> the current choice of AES-CBC. My understanding of AE ciphers (with or
> without associated data) is that you don't have to design that
> yourself, which is nice.
>

IMO it's impossible to solve this attack within TCE, because it requires
ensuring consistency at the row level, but TCE obviously works at column
level only.

I believe TCE can do AEAD at the column level, which protects against
attacks that flipping bits, and similar attacks. It's just a matter of
how the client encrypts the data.

Extending it to protect the whole row seems tricky, because the client
may not even know the other columns, and it's not clear to me how it'd
deal with things like updates of the other columns, hint bits, dropped
columns, etc.

It's probably possible to get something like this (row-level AEAD) by
encrypting enriched data, i.e. not just the card number, but {user ID,
card number} or something like that, and verify that in the webapp. The
problem of course is that the "user ID" is just another column in the
table, and there's nothing preventing the DBA from modifying that too.

So I think it's pointless to try extending this to row-level AEAD.

regards

--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2021-12-07 21:59:06 Re: Why doesn't pgstat_report_analyze() focus on not-all-visible-page dead tuple counts, specifically?
Previous Message Bossart, Nathan 2021-12-07 21:20:46 Re: Is it correct to update db state in control file as "shutting down" during end-of-recovery checkpoint?