I had been using MySQL as database and had planned to move to postgresql. I had used aes_encrypt and aes_decrypt functions in MySQL extensively throughout my application. So whenever the encryption/decrytion fails, MySQL automatically returns ‘null’.
I am unsure how to handle the same in postgresql. Tried using the pgp_sym_encrypt/pgp_sym_decrypt functions. If the encryption key is wrong, it throws error “Wrong key/corrupt data”. I tried searching for some functions that could capture this error and return ‘null’ as in MySQL so that I need not modify my code. I had been searching but could not find one.
Has anybody used any error handling mechanism for individual queries? I had found that error handling can be done for procedures. But, I had to completely rewrite the entire application for that.
If you could share some details, it would be of great help. Thanks.
If you wish to avoid modifying your code and have the functions return
NULLon error, you can do this by wrapping them in a PL/PgSQL function that uses aBEGIN ... EXCEPTIONblock to trap the error.To do this, first I get the SQLSTATE for the error:
I could use this directly in the error handler, but I prefer to use a symbolic name, so I look up the error name associated with 39000 in Appendix A – Error codes, finding that it’s the generic function call error
external_routine_invocation_exception. Not as specific as we would’ve liked, but it’ll do.Now a wrapper function is required. Something like this must be defined, with one function for each overloaded signature of
pgp_sym_decryptthat you wish to support. For the(bytea,text)form that returnstext, for example:I’ve chosen to preseve the original error in a
DEBUGlevel message. Here’s a comparison of the original and wrapper, with full message verbosity and debug level output.Enable debug output to show the
RAISE. Note that it also shows the *original query text of thepgp_decrypt_symcall, including parameters.New wrapped function still reports the error if detailed logging is enabled, but returns
NULL:compared to the original, which fails:
Note that both forms show the parameters the function was called with when it failed. The parameters won’t be shown if you’ve used bind parameters (“prepared statements”), but you should still consider your logs to be security critical if you’re using in-database encryption.
Personally, I think it’s better to do crypto in the app, so the DB never has access to the keys.