1

I am trying to decrypt a message with pgcrypto that is encrypted with AES GCM 256.

Specifications of the encryption:

Encryption algorithm     AES
Key                      [secret of listener] (64-character-long hexadecimal string in configuration)
Key length               256 bits (32 bytes)
Block mode               GCM
Padding                  None
Initialization vector    In HTTP header (X-Initialization-Vector)
Authentication tag       In HTTP header (X-Authentication-Tag)

So I receive a:

  • body
  • key
  • iv_header
  • auth_tag

I tried the below

with base as (
select
    'F8E2F759E528CB69375E51DB2AF9B53734E393' as body,
    '000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F' as key,
    '3D575574536D450F71AC76D8' as iv_header,
    '19FDD068C6F383C173D3A906F7BD1D83' as auth_tag
),
out as (
    select
        decrypt_iv(
            convert_to(concat(decode(body,'hex'),decode(auth_tag,'hex')),'LATIN1'),
            decode(key, 'hex'),
            decode(iv_header, 'hex'),
            'aes/pad:none'
        )
    from base
)

select * from out

I keep getting the error decrypt_iv error: Data not a multiple of block size while I would expect to get the encoded message {"type": "PAYMENT"}

I expect that something goes wrong in the decoding and concatenating of body and auth_tag, but can't figure out what.

Some notes on what/why I did that

  • I concat the auth_tag to the body as several sources describe it that way.
  • I use the convert_to function as it seems the only way to concatenate two bytea values

I manage to decrypt this message in other languages (i.e. Snowflake or Python)

If anyone sees what I am doing wrong or has some directions it is highly appreciated.

Chris Rutte
  • 173
  • 1
  • 14
  • Could you show the code that does it in python? – jjanes Mar 01 '21 at 18:00
  • Hi @jjanes, a sample for different languages can be found here https://peachpayments.docs.oppwa.com/tutorials/webhooks/decryption-example My feeling is that the Scala sample can be helpful as it also appends the auth_tag to the encrypted body. Hope this clarifies. – Chris Rutte Mar 01 '21 at 18:55

1 Answers1

1

pgcrypto only says it supports cbc and ecb. I'm not a cryptographer, but I don't think either of those is the same thing as GCM. So I don't think you can do this with pgcrypto. I don't know why it leads to the exact error you get, but it also doesn't surprise me.

If I really needed to do this inside the database, I think I do it by writing a function using pl/python3u.

jjanes
  • 37,812
  • 5
  • 27
  • 34
  • Thanks @jjanes, that makes sense, I hoped GCM would be a variant of of CBC/EBC. I think we'll just do the decryption outside of the database. Thanks, Chris – Chris Rutte Mar 03 '21 at 13:06