0

A group of bankers will store sensitive financial information on a server owned by a third party. I represent the 3rd party server.

The financial information will be stored as plain text on the server except that the customer's Account Numbers will be encrypted. The banks do not want us to know their customers' account numbers.

My question is, how safe is it to use the Account Number as a nonce if it is also the message being encrypted when using AES-GCM? So, how safe is it to encrypt as follows: AES-GCM[Key, Nonce = AccountNumber, Message = Account Number].

I know this is an example of deterministic encryption and it would be best to use GCM-SIV mode but I cannot find any libraries that implement this encryption that I can use with the .NET Framework.

On a side note, has anyone ever used Miscreant .NET? As far as I know it has not received FIPS compliance.

Here is an example of the design:

Banker's Data: 
Note, that the AccountNumber is a primary key and will not be repeated.  Therefore, nonce = message = AccountNumber will never be repeated.

PK*AccountNumber   Balance     Nonce
1                  $10,000     1
2                  $15,000     2
3                  $20,000     3

3rd Party Server
AccountNumber   Balance
A2B3C4          $10,000
T4K8S9          $15,000
L6D9S8          $20,000

If the Banker wants to query the 3rd party server for the balance of AccountNumber = 1, he will query the server for AES-GCM(Key,Nonce=1,Message=1)='A2B3C4'. Since only the banker knows the Key and AccountNumber only he can know which record to query for. This is in essence a zero-knowledge encryption scheme where only the Banker has any knowledge of the key, nonce or message.

user66406
  • 1
  • 1

2 Answers2

1

I think this is a bad idea for a few reasons:

  • In GCM mode, if you encrypt two messages with the same nonce, then the messages' plaintexts may be retrievable from the ciphertexts. So if you have two different messages about the same customer that both use the customer id as the nonce, then your encryption may be broken.

  • When a user retrieves a ciphertext, how will they know the customer ID to use as the nonce? Usually the nonce is included with the ciphertext so that the user can use it with the key to decrypt the ciphertext, but if you do this, then the customer ID will be in plaintext.

Is there some reason that you don't want to use a random nonce as is normally done? If there isn't a specific reason to go off the standard path, then you should avoid doing so.

Macil
  • 528
  • 4
  • 8
1

You don’t need encryption to accomplish your goal. A more secure solution is for the bank to use a keyed hash function (also known as a pseudo-random function) that isn’t invertible. They bank would keep the key secret from you.

The standard PRF in 2019 would be HMAC-SHA256. So the bank would send you HMAC_SHA256(key,account_number) instead of the actual account number. The bank would be able to do lookups (typically called “point queries”, meaning exact-match queries) via account number by computing the HMAC first.

For what it’s worth, I know from personal experience this exact solution is already used at large scale in the banking industry. The HMACs are truncated to 128 bits and stored as UUIDs in practice. Banks often use a different key with each of their interchange partners to prevent correlation.

rmalayter
  • 2,297
  • 17
  • 24