From: | Jacob Champion <pchampion(at)vmware(dot)com> |
---|---|
To: | "tomas(dot)vondra(at)enterprisedb(dot)com" <tomas(dot)vondra(at)enterprisedb(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-17 00:41:00 |
Message-ID: | 2738ecdfc23fdc149a91bea45cb235d09c453a3f.camel@vmware.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Thu, 2021-12-09 at 11:04 +0100, Tomas Vondra wrote:
> On 12/9/21 01:12, Jacob Champion wrote:
> >
> > The rabbit hole I led you down is one where we use the rest of the row
> > as AD, to try to freeze pieces of it in place. That might(?) have some
> > useful security properties (if the client defines its use and doesn't
> > defer to the server). But it's not what I intended to propose and I'd
> > have to think about that case some more.
So after thinking about it some more, in the case where the client is
relying on the server to return both the encrypted data and its
associated data -- and you don't trust the server -- then tying even
the entire row together doesn't help you.
I was briefly led astray by the idea that you could include a unique or
primary key column in the associated data, and then SELECT based on
that column -- but a motivated DBA could simply corrupt state so that
the row they wanted got returned regardless of the query. So the client
still has to have prior knowledge.
> > In my credit card example, I'm imagining something like (forgive the
> > contrived syntax):
> >
> > SELECT address, :{aead(users.credit_card, 'user(at)example(dot)com')}
> > FROM users WHERE email = 'user(at)example(dot)com';
> >
> > UPDATE users
> > SET :{aead(users.credit_card, 'user(at)example(dot)com')} = '1234-...'
> > WHERE email = 'user(at)example(dot)com';
> >
> > The client explicitly links a table's column to its AD for the duration
> > of the query. This approach can't scale to
> >
> > SELECT credit_card FROM users;
> >
> > because in this case the AD for each row is different, but I'd argue
> > that's ideal for this particular case. The client doesn't need to (and
> > probably shouldn't) grab everyone's credit card details all at once, so
> > there's no reason to optimize for it.
>
> Maybe, but it seems like a rather annoying limitation, as it restricts
> the client to single-row queries (or at least it looks like that to me).
> Yes, it may be fine for some use cases, but I'd bet a DBA who can modify
> data can do plenty other things - swapping "old" values, which will have
> the right AD, for example.
Resurrecting old data doesn't help the DBA read the values, right? I
view that as similar to the "increasing account balance" problem, in
that it's definitely a problem but not one we're trying to tackle here.
(And I'm not familiar with any solutions for resurrections -- other
than having data expire and tying the timestamp into the
authentication, which I think again requires AD. Revoking signed data
is one of those hard problems. Do you know a better way?)
> OK. In any case, I think we shouldn't require this capability from the
> get go - it's fine to get the simple version done first, which gives us
> privacy / protects against passive attacker. And then sometime in the
> future improve this further.
Agreed. (And I think the client should be able to enforce encryption in
the first place, before I distract you too much with other stuff.)
--Jacob
From | Date | Subject | |
---|---|---|---|
Next Message | Yugo NAGATA | 2021-12-17 00:47:18 | Allow DELETE to use ORDER BY and LIMIT/OFFSET |
Previous Message | Euler Taveira | 2021-12-17 00:31:15 | Re: Confused comment about drop replica identity index |