1

I am currently writing an application which needs to store user data encrypted in the database. One of the requirements is that some of the data stored in the database needs to be encrypted in a way that we (the database administrators, with full read access to the raw data in the table) can not decrypt it. Clearly, we need to encrypt this data using a private key derived from some user-supplied information which we are unable to see. We will store the public key of this pair, and use it to encrypt any data which needs to be added to their account.

Unfortunately, I don't know how to obtain a private key pair for the user. We use Google Sign-In for our application, and thus the user does not have a password. What other information can I use as the input for a KDF to derive an encryption key for the user?

Here is the information I recieve when the user authenticates via Google Sign-In:

{
  // These fields vary each time the user logs in
  "at_hash":"XXXXXXXXXXXXXXXXXXXXXX",
  "aud":"XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
  "azp":"XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",

  // This is general user information which we need to know
  // These can not be used as the KDF input because we also need
  // to know the plaintext values as well
  "email":"example@example.com",
  "email_verified":true,
  "name":"John Doe",
  "given_name":"John",
  "family_name":"Doe",
  "locale":"en",

  // This value can change if the user changes their profile picture
  // Also, it's not really a secure KDF input...
  "profile_picture": "https://example.com/xxx/profile.png",

  // This value is the user ID. We are already using it as the database primary key.
  "sub":"XXXXXXXXXXXXXXXXXXXXX",

  // These values seem to be specific to Google's OAuth stuff.
  // The first three vary between all requests, and the last one
  // is constant across all requests.
  "exp":0000000000,
  "iat":0000000000,
  "jti":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "iss":"accounts.google.com"
}

How else can I create a private key for the user from some deterministic information, such that I can only obtain that when they log in?

vikarjramun
  • 121
  • 5

1 Answers1

2

Long story short, you can't unfortunately.

You could ask a user to provide an encryption key the first time they login, then store that encrypted with the token, but of course the token will change if they reauthenticate (as you identified), so they would have to provide their key again at that point. For you to be able to decrypt the user data you'd have to first ascertain the token to decrypt the key, which depending how your application is set up and the access your DBAs have might be enough.

LTPCGO
  • 965
  • 1
  • 5
  • 22
  • Yeah, that's what I thought. Unfortunately, creating a password as well as using Google Sign-in seems to be quite redundant. I'll see what I can do though. Thanks! – vikarjramun Sep 24 '19 at 03:07