PostgreSQL: Encrypt Column With pgcrypto - postgresql

I need to encrypt some columns in a PostgreSQL 9.6 database. The data being encrypted is inherently sensitive; however, the data are not passwords or other authentication credentials. This data will need to be decrypted for statistical analysis and consumption by users.
After reading several questions and answers:
Storing encrypted data in Postgres
https://dba.stackexchange.com/questions/24370/how-to-use-aes-encryption-in-postgresql
https://dba.stackexchange.com/questions/59942/secure-postgresql-database-encryption
... and considering these comments:
... it seems the biggest problem with using the pgcrypto module is the storage of keys in the same database.
This begs the question:
Is it consistent with best practices to store the key in a different database and access it via a foreign data wrapper, such as Postgresql_FDW?

Secret storage is a common issue when using crypto mecanisms.
pgcrypto does not povide key storage, you are free to store the key where you want and protect it as you can.
Storing the key in another database, if managed by the same DBA does not provide much security as DBA may access it the same way.
Ideally, you would store the key in a secure vault and request it from your application in order to construct the queries. It will still be visible from DBA while the request is running through select * from pg_stat_activity.
You may set the key for a SQL session wide use through set session my.vars.cryptokey = 'secret'; then use it into your queries with the following syntax : current_setting('my.vars.cryptokey')::text
To be (almost) transparent from the application point of view, PostgreSQL rules may help for translating secure_column to the call to decrypt function with the session stored key. For inserting, a pre-insert trigger would be required.

Related

Postgres TDE capability only for specific schema

As part of GDPR requirement we need to encrypt data at rest.
We are planning to use Postgres and from the below links looks like TDE can be achieved in Postgres as well.
https://www.enterprisedb.com/blog/postgres-and-transparent-data-encryption-tde
https://www.cybertec-postgresql.com/en/products/postgresql-transparent-data-encryption/
When we have multiple schema in Postgres, is it possible to apply TDE only in a particular schema?
Unfortunately it is not possible to just encrypt a schema because, when you install PostgreSQL TDE, you initialize the whole database with the encryption key.
Like you can see in the picture here:
there is a reason for this: if we allow encryption on a per-table level (or per schema or per database, doesn't matter) we got to manage an infinite number of keys. this is especially true during point-in-time-recovery and all that. this is why we decided to do the encryption on the instance level. one key. the core advantage is: we can easily encrypt all parts of the instance including the WAL, temp files, and so on (basically everything but the clog).
don't expect this to change - go for full encryption.
we can help you with that.
cheers from cybertec :)
i hope you like the feature :)
hans

storing certain fields encrypted in postgres with pgcrypto

The postgres docs on "Encryption Options" say:
Encryption For Specific Columns
The pgcrypto module allows certain fields to be stored encrypted. This is useful if only some of the data is sensitive. The client supplies the decryption key and the data is decrypted on the server and then sent to the client.
The decrypted data and the decryption key are present on the server for a brief time while it is being decrypted and communicated between the client and server. This presents a brief moment where the data and keys can be intercepted by someone with complete access to the database server, such as the system administrator.
"pgcrypto" is linked to the pgcrypto docs, which discuss a variety of available hashing and encryption functions.
But it's not clear to me how I'm meant to put them together to implement the solution the "Encryption Options" docs suggested, to allow certain fields (ie columns) to be stored encrypted. I am having trouble finding any docs or examples.
Can anyone point me to doc or examples explaining how you use pgcrypto to allow certain fields to be stored encrypted?

How can I encrypt just a single table data in redshift database

How can I encrypt just a single table data in redshift database?
I see that encryption is a cluster level setting. But I need to encrypt just 1 table and not all the tables of the database.
I have user personal information in the table that I want to encrypt.
No. As you say, encryption is a cluster-level setting.
You could encrypt the data in the table yourself, but this makes it hard to write useful SQL queries.

How to store passwords exclusively through PostgreSQL

How would I store passwords exclusively in PostgreSQL? I am aware of the pgcrypto library that can be used with PostgreSQL as is outlined here, or below:
INSERT INTO users (name, password) VALUES ('jdoe', crypt('password', gen_salt('md5')));
However, it is still possible that passwords would be stored in plain text within PostgreSQL server logs. Another complicating factor is I do not have direct control over the log configuration.
Is there any way to completely hide the values in a server column, even from the logs?

Is there some security advantage to using pgcrypto instead of partition-level encryption?

The document here: http://www.postgresql.org/docs/8.2/static/encryption-options.html describes several approaches to encrypting data when using postgresql.
I would like to know if there's any security advantage to encrypting specific columns using pgcrypto instead of simply encrypting the entire partition on which the database resides. It seems to me that pgcrypto is cumbersome to use(instead of just using SQL queries without having to worry about things being encrypted) so there should be a reason for its existence. Is it simply that people may not have the ability to manage the database server(shared hosts/etc...) so they would have to make-do with pgcrypto, or is there a security reason?
In my particular case, the application code and the database are on the same host, so compromising the server itself while it is live would result in the data being leaked either way(one could look for the encryption key in the code in one case, or simply retrieve the data from the mounted volume in the other).
Edit: I forgot to mention, also in this particular case, the data is used by the server not the client, ie, the client can't provide the key at run-time it would have to be on the server in the application code.
You can give the DBA SQL level access without compromising data.
You can have separate encryption keys for different data
Your backups (dumps) are encrypted
If the client provides the encryption keys, The server does not have to be trusted
If You separate the app server from the DB server, the encryption keys can be on the app server only.
You can encrypt only a part of the data.
Last but not the least: There is more to pgcrypto than symmetric single-key encryption, like asymmetric encryption, cryptographic hashing, cryto-safe PRNG, password-hashing.