Search code examples
postgresqlgnupg

pgcrypto Postgresql PGP pgp_pub_decrypt with password


I have been experiencing few problems with data encryption over pgcrypto with Postgresql 8.4.

First case : works fine :

select pgp_pub_decrypt(pgp_pub_encrypt('fsck', dearmor(pubkey),'compress-algo=1, cipher-algo=aes256'),dearmor(seckey)) from keytbl where keytbl.id=1

-> returns "fsck"

key 1 is pgp with no password

Second case : doesn't work

select pgp_pub_decrypt(pgp_pub_encrypt('fsck', dearmor(pubkey),'compress-algo=1, cipher-algo=aes256'),dearmor(seckey),'password') from keytbl where keytbl.id=2

-> returns ERREUR: Corrupt data

When i generate keys with password pgcrypto doesn't want to decrypt the message crypted with the public key ....

Anyone got a guess ? This is driving me mad...


Solution

  • This appears to be a known bug in at least 8.4 and 9.0. I have avoided this in the past by avoiding using the passphrase functionality and using pgp_sym_encrypt and pgp_sym_decrypt to manage the keys' passphrases.

    In general if this is giving you a problem your best option is to encrypt the keys with a passphrase separately using well-tested functions.

    To give you an idea of how we do it:

    create or replace function user__replace_keys
    (in_public_key bytea, in_private_key bytea, in_passphrase text)
    RETURNS user_key
    LANGUAGE SQL AS
    $$
    UPDATE user_key
       SET last_resort_key = pgp_pub_encrypt(
                                 pgp_pub_decrypt(
                                       last_resort_key,
                                       pgp_sym_decrypt_bytea(priv_key, $3)
                                 ), $2
                             ),
           pub_key = $2,
           priv_key = pgp_sym_encrypt_bytea($2, $3)
     WHERE login = SESSION_USER
    RETURNING *;
    $$;
    

    Note that the private key sent to the server must not be password encryted. We might actually generate it on the server or in middleware to avoid problems. This avoids bugs of the sort you are experiencing.